Python Library Installation

Discussions on extending SharpCap using the built in Python scripting functionality
lightpath
Posts: 4
Joined: Thu Dec 21, 2017 3:47 am

Python Library Installation

#1

Post by lightpath »

Hey there fellow scripters-

I'm working on an all-sky camera script and I was wondering if there's a way to install 3'rd party libs into IronPython. In particular I was looking at Astral, so I could know when the sun is up, and disable dark frames for example.

Does anyone know a better way to do this within the tools that ship with Ironpython in Sharpcap?

Thanks very much for putting IronPython into SharpCap by the way- It's wonderful!

Mark.
User avatar
admin
Site Admin
Posts: 13177
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: Python Library Installation

#2

Post by admin »

Hi Mark,

glad you like the IronPython scripting :)

I think it should be fairly simple - just use sys.path.append('c:\my library') to make IronPython search for imports in an additional folder (see https://stackoverflow.com/questions/314 ... her-source).

Iron Python can only load external modules that are pure python (not ones that have C/C++ components), so you have to be careful of that. I expect that if you set up a separate install of python 2.7 and 'pip install' the modules you want into that, you may just be able to point SharpCap at it's module directory.

cheers,

Robin
lightpath
Posts: 4
Joined: Thu Dec 21, 2017 3:47 am

Re: Python Library Installation

#3

Post by lightpath »

Those are neat solutions, I'll give them a try! Thanks Robin!

Mark.
lightpath
Posts: 4
Joined: Thu Dec 21, 2017 3:47 am

Re: Python Library Installation

#4

Post by lightpath »

Unfortunately the dependencies got irritating for Astral. I'm going to try and solve this problem another way. Your solution did work, however, thanks!
TimHaymes
Posts: 51
Joined: Sun May 28, 2017 8:11 am

Re: Python Library Installation / access to system time?

#5

Post by TimHaymes »

I have a question about scripting. Is it possible to pole the system time, so that I can write a script that will enable me to start an SER recording at a specified time for a specified duration ? I use the QHY174m-GPS. Based on what I have read here, it may be possible to include additional libraries. Any suggestion/example welcome.

Im not a regular scripter, i just hack examples ;) Infact, i have not used ironPython.

Tim
User avatar
admin
Site Admin
Posts: 13177
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: Python Library Installation

#6

Post by admin »

Hi,

Yes, you can definitely do something like this to wait until a certain time. There are examples in all sorts of places on the web showing how to do this with Python that can be reused in SharpCap – for instance one approach is shown here

https://stackoverflow.com/questions/448 ... rtain-time

Hope this helps, Robin
Jean-Francois
Posts: 361
Joined: Sun Oct 13, 2019 10:52 am
Location: Germany

Re: Python Library Installation

#7

Post by Jean-Francois »

Hello,

In the past weeks, I start learning Python and the scripting with/for SharpCap.
OK ... it is not Python ... it is IronPython with .NET parts.

In other forum subject, somebody gives some scripts for the polar alignment with images/plate solving.
I test the scripts (but, I think one bug somewhere and a problem ... the scripts use IronPython and R scripts.
Also 3 scripts with user intervention in between for copying the R results in the last Python script.

My goal is to rewrite all the script in only 1 Python script.
The problem is the non-linear equations system optimization ... R has the routine, IronPython not directly ... I read that NumPy is not compatible with IronPython (C vs. C#) ... also I start the search for a replacement library. That takes more than 1 week and the reading of ~100 websites.

I found the ALGLIB free library. I found how to integrate in "SharpCap"-IronPython.

Concerning the Python library in SharpCap ... I remark the following:
- a file "PythonLib.zip" is in the SharpCap directory
- if I unpack the zip file, SharpCap generates a new zip file
- if I delete the zip file, SharpCap generates a new zip file
... OK, SharpCap likes only the Python zipped !

The last IronPython version is the 2.7.10, SharpCap uses the 2.7.9 version ... is the 10-9 difference relevant for the use with SharpCap ?

Other question ... Do you have somewhere a list of (all) the SharpCap functions with parameter description ?


Regards,
Jean-Francois
User avatar
admin
Site Admin
Posts: 13177
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: Python Library Installation

#8

Post by admin »

Hi,

the-zip file is part of the SharpCap installation and if you change it or delete it and then run SharpCap from the shortcuts on the desktop or in the start menu, Windows will repair the installation and put the zip file back the way it was. If you want to work around this you can either run SharpCap by directly clicking on it in the install folder or create your own shortcut to the .exe file.

To be honest though, the correct way to add extra library paths to SharpCap's python is to use

Code: Select all

sys.path.append(r"c:\myfolder\pylibs")
However, beware that you can only import Python libraries that are implemented in pure Python – if the library you have implements code in C then I believe it cannot be used inside IronPython.

I don't think the difference between 2.7.9 and 2.7.10 is significant – as far as I can see 2.7.10 simply add support for a newer version of the Microsoft .Net, which isn't currently relevant in the case of SharpCap.

I'm afraid to say that I don't maintain the document listing all the available method calls. It would be an interesting project to try to work out a way of generating such a document automatically though. Something to think about for the future.

Cheers, Robin
Jean-Francois
Posts: 361
Joined: Sun Oct 13, 2019 10:52 am
Location: Germany

Re: Python Library Installation

#9

Post by Jean-Francois »

Hello Robin,

Thanks for the information.

Concerning the function list ... OK, I will in future ask you "How to do this ? Which function can be used ?"

Concerning the "script source sharing library" ...
I write a small script for performing a simple GOTO of the mount. I do some experiment and it was necessary to start from a defined position.

Here a script in 2 versions.
- one version usable from the Python console
- one version generating a SharpCap menu (a link has to be inserted in the "SharpCap Settings"-"Startup Scripts")

The script send a GOTO command with RA and DEC coordinates. The user is responsable to give RA and DEC values that not produce a collision.
The mount driver is responsable for any displacement of the mount.

Code: Select all

# *******************************************************************************************
# 
# SharpCap script "Test_GOTO.py"
# 2020/08/30 Jean-Francois Pittet
# Version: 1.0
#
# The telescope has to be connected before use of the script and the tracking mode has to be 
# activated.
#
# 1. Decimal input: RA limits [0 .. 24]
#                   DEC limits [-90 .. 90]
#    Values outside these limits produce an error
#
# 2. deg/min/sec input: RA ... negative values produce an error
#                       DEC ... negative values of min and sec are ignored
#    Values outside these limits produce an error
#
# *******************************************************************************************

import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
clr.AddReference("ASCOM.DriverAccess")

from math import copysign

from System.Windows.Forms import Application, Button, CheckBox, Form, Label, Panel, RadioButton, TextBox
from System.Drawing import Point
from ASCOM.DriverAccess import *

class ChecksAndRadiosForm(Form):
    def __init__(self):
        self.Text = "Slew the mount to the RA and DEC position"
        self.Width = 450
        self.Height = 200
        
        self.setupCheckButtons()
        self.setupRadioButtons()
      
    def setupCheckButtons(self):   
        self.label_RA = Label()
        self.label_RA.Text = "RA [0.0 ... 24.0]:"	# The input values are tested automatically
        self.label_RA.Location = Point(25, 50)
        self.label_RA.Height = 25
        self.label_RA.Width = 100
        
        self.label_DEC = Label()
        self.label_DEC.Text = "DEC [-90 ... 90]:"	# The input values are tested automatically
        self.label_DEC.Location = Point(25, 75)
        self.label_DEC.Height = 25
        self.label_DEC.Width = 100

        self.textbox_RA = TextBox()
        self.textbox_RA.Text = ""
        self.textbox_RA.Location = Point(125, 45)
        self.textbox_RA.Width = 80

        self.textbox_DEC = TextBox()
        self.textbox_DEC.Text = ""
        self.textbox_DEC.Location = Point(125, 70)
        self.textbox_DEC.Width = 80
        
        self.textbox_RA_std = TextBox()
        self.textbox_RA_min = TextBox()
        self.textbox_RA_sec = TextBox()
        self.textbox_RA_std.Text = "0"
        self.textbox_RA_min.Text = "0"
        self.textbox_RA_sec.Text = "0"
        self.textbox_RA_std.Location = Point(230, 45)
        self.textbox_RA_min.Location = Point(260, 45)
        self.textbox_RA_sec.Location = Point(290, 45)
        self.textbox_RA_std.Width = 25
        self.textbox_RA_min.Width = 25
        self.textbox_RA_sec.Width = 40
        self.textbox_RA_std.Enabled = False
        self.textbox_RA_min.Enabled = False
        self.textbox_RA_sec.Enabled = False

        self.textbox_DEC_deg = TextBox()
        self.textbox_DEC_min = TextBox()
        self.textbox_DEC_sec = TextBox()
        self.textbox_DEC_deg.Text = "0"
        self.textbox_DEC_min.Text = "0"
        self.textbox_DEC_sec.Text = "0"
        self.textbox_DEC_deg.Location = Point(230, 70)
        self.textbox_DEC_min.Location = Point(260, 70)
        self.textbox_DEC_sec.Location = Point(290, 70)
        self.textbox_DEC_deg.Width = 25
        self.textbox_DEC_min.Width = 25
        self.textbox_DEC_sec.Width = 40
        self.textbox_DEC_deg.Enabled = False
        self.textbox_DEC_min.Enabled = False
        self.textbox_DEC_sec.Enabled = False

        self.button_GOTO = Button()
        self.button_GOTO.Text = 'GOTO'
        self.button_GOTO.Location = Point(25, 125)
        self.button_GOTO.Click += self.goto

        self.button_Exit = Button()
        self.button_Exit.Text = 'Exit'
        self.button_Exit.Location = Point(125, 125)
        self.button_Exit.Click += self.exit

        self.AcceptButton = self.button_GOTO
        self.CancelButton = self.button_Exit

        self.Controls.Add(self.label_RA)
        self.Controls.Add(self.label_DEC)
        self.Controls.Add(self.textbox_RA)
        self.Controls.Add(self.textbox_DEC)
        self.Controls.Add(self.textbox_RA_std)
        self.Controls.Add(self.textbox_RA_min)
        self.Controls.Add(self.textbox_RA_sec)
        self.Controls.Add(self.textbox_DEC_deg)
        self.Controls.Add(self.textbox_DEC_min)
        self.Controls.Add(self.textbox_DEC_sec)
        self.Controls.Add(self.button_GOTO)
        self.Controls.Add(self.button_Exit)
        
    def setupRadioButtons(self):
        self.radio1 = RadioButton()
        self.radio1.Text = "xx.xxx (deg)"
        self.radio1.Location = Point(120, 10)
        self.radio1.Checked = True
        self.radio1.CheckedChanged += self.checkedChanged
        
        self.radio2 = RadioButton()
        self.radio2.Text = "xx (deg) yy (min) zz.zz (sec)"
        self.radio2.AutoSize = True
        self.radio2.Location = Point(230, 11)
        self.radio2.CheckedChanged += self.checkedChanged
        
        self.Controls.Add(self.radio1)
        self.Controls.Add(self.radio2)      
        
    def checkedChanged(self, sender, args):
        if not sender.Checked:
            return
        if self.radio1.Checked == True:
            self.textbox_RA.Enabled = True
            self.textbox_DEC.Enabled = True
            self.textbox_RA_std.Enabled = False
            self.textbox_RA_min.Enabled = False
            self.textbox_RA_sec.Enabled = False
            self.textbox_DEC_deg.Enabled = False
            self.textbox_DEC_min.Enabled = False
            self.textbox_DEC_sec.Enabled = False
            
        else:
            self.textbox_RA.Enabled = False
            self.textbox_DEC.Enabled = False
            self.textbox_RA_std.Enabled = True
            self.textbox_RA_min.Enabled = True
            self.textbox_RA_sec.Enabled = True
            self.textbox_DEC_deg.Enabled = True
            self.textbox_DEC_min.Enabled = True
            self.textbox_DEC_sec.Enabled = True

        
    def goto(self, sender, event):
		t = Telescope("ASCOM.Simulator.Telescope")
		if self.radio1.Checked == True:
			RA = float(self.textbox_RA.Text)
			DEC = float(self.textbox_DEC.Text)
		else:
			RA = float(self.textbox_RA_min.Text) / 60.0 + float(self.textbox_RA_sec.Text) / 3600.0
			RA = RA + float(self.textbox_RA_std.Text)
			DEC = abs(float(self.textbox_DEC_min.Text)) / 60.0 + abs(float(self.textbox_DEC_sec.Text)) / 3600.0
			DEC = DEC + abs(float(self.textbox_DEC_deg.Text))
			DEC = DEC * copysign(1, float(self.textbox_DEC_deg.Text))
			
			
		print("GOTO to RA position : %f" % (RA))
		print("GOTO to DEC position: %f" % (DEC))
		print
		t.SlewToCoordinates(RA, DEC)

    def exit(self, sender, event):
    	print("Stop GOTO script")
        self.Close()

form = ChecksAndRadiosForm()
Application.Run(form)
And ...

Code: Select all

# *******************************************************************************************
# 
# SharpCap script "Test_GOTO_menu.py"
# 2020/08/30 Jean-Francois Pittet
# Version: 1.0
#
# This script is to be placed in the list of the Startup script list:
# Menu "File", "SharpCap Settings", "Startup Scripts"
# The menu "GOTO" appears on the SharpCap window.
#
# The telescope has to be connected before use of the script and the tracking mode has to be 
# activated.
#
# 1. Decimal input: RA limits [0 .. 24]
#                   DEC limits [-90 .. 90]
#    Values outside these limits produce an error
#
# 2. deg/min/sec input: RA ... negative values produce an error
#                       DEC ... negative values of min and sec are ignored
#    Values outside these limits produce an error
#
# *******************************************************************************************

import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
clr.AddReference("ASCOM.DriverAccess")

from math import copysign

from System.Windows.Forms import Application, Button, CheckBox, Form, FormStartPosition, Label, Panel, RadioButton, TextBox
from System.Drawing import Point
from ASCOM.DriverAccess import *

class ChecksAndRadiosForm(Form):
    def __init__(self):
        self.Text = "Slew the mount to the RA and DEC position"
        self.Width = 450
        self.Height = 200
        
        self.setupCheckButtons()
        self.setupRadioButtons()
      
    def setupCheckButtons(self):   
        self.label_RA = Label()
        self.label_RA.Text = "RA [0.0 ... 24.0]:"	# The input values are tested automatically
        self.label_RA.Location = Point(25, 50)
        self.label_RA.Height = 25
        self.label_RA.Width = 100
        
        self.label_DEC = Label()
        self.label_DEC.Text = "DEC [-90 ... 90]:"	# The input values are tested automatically
        self.label_DEC.Location = Point(25, 75)
        self.label_DEC.Height = 25
        self.label_DEC.Width = 100

        self.textbox_RA = TextBox()
        self.textbox_RA.Text = ""
        self.textbox_RA.Location = Point(125, 45)
        self.textbox_RA.Width = 80

        self.textbox_DEC = TextBox()
        self.textbox_DEC.Text = ""
        self.textbox_DEC.Location = Point(125, 70)
        self.textbox_DEC.Width = 80
        
        self.textbox_RA_std = TextBox()
        self.textbox_RA_min = TextBox()
        self.textbox_RA_sec = TextBox()
        self.textbox_RA_std.Text = "0"
        self.textbox_RA_min.Text = "0"
        self.textbox_RA_sec.Text = "0"
        self.textbox_RA_std.Location = Point(230, 45)
        self.textbox_RA_min.Location = Point(260, 45)
        self.textbox_RA_sec.Location = Point(290, 45)
        self.textbox_RA_std.Width = 25
        self.textbox_RA_min.Width = 25
        self.textbox_RA_sec.Width = 40
        self.textbox_RA_std.Enabled = False
        self.textbox_RA_min.Enabled = False
        self.textbox_RA_sec.Enabled = False

        self.textbox_DEC_deg = TextBox()
        self.textbox_DEC_min = TextBox()
        self.textbox_DEC_sec = TextBox()
        self.textbox_DEC_deg.Text = "0"
        self.textbox_DEC_min.Text = "0"
        self.textbox_DEC_sec.Text = "0"
        self.textbox_DEC_deg.Location = Point(230, 70)
        self.textbox_DEC_min.Location = Point(260, 70)
        self.textbox_DEC_sec.Location = Point(290, 70)
        self.textbox_DEC_deg.Width = 25
        self.textbox_DEC_min.Width = 25
        self.textbox_DEC_sec.Width = 40
        self.textbox_DEC_deg.Enabled = False
        self.textbox_DEC_min.Enabled = False
        self.textbox_DEC_sec.Enabled = False

        self.button_GOTO = Button()
        self.button_GOTO.Text = 'GOTO'
        self.button_GOTO.Location = Point(25, 125)
        self.button_GOTO.Click += self.goto

        self.button_Exit = Button()
        self.button_Exit.Text = 'Exit'
        self.button_Exit.Location = Point(125, 125)
        self.button_Exit.Click += self.exit

        self.AcceptButton = self.button_GOTO
        self.CancelButton = self.button_Exit

        self.Controls.Add(self.label_RA)
        self.Controls.Add(self.label_DEC)
        self.Controls.Add(self.textbox_RA)
        self.Controls.Add(self.textbox_DEC)
        self.Controls.Add(self.textbox_RA_std)
        self.Controls.Add(self.textbox_RA_min)
        self.Controls.Add(self.textbox_RA_sec)
        self.Controls.Add(self.textbox_DEC_deg)
        self.Controls.Add(self.textbox_DEC_min)
        self.Controls.Add(self.textbox_DEC_sec)
        self.Controls.Add(self.button_GOTO)
        self.Controls.Add(self.button_Exit)
        
    def setupRadioButtons(self):
        self.radio1 = RadioButton()
        self.radio1.Text = "xx.xxx (deg)"
        self.radio1.Location = Point(120, 10)
        self.radio1.Checked = True
        self.radio1.CheckedChanged += self.checkedChanged
        
        self.radio2 = RadioButton()
        self.radio2.Text = "xx (deg) yy (min) zz.zz (sec)"
        self.radio2.AutoSize = True
        self.radio2.Location = Point(230, 11)
        self.radio2.CheckedChanged += self.checkedChanged
        
        self.Controls.Add(self.radio1)
        self.Controls.Add(self.radio2)      
        
    def checkedChanged(self, sender, args):
        if not sender.Checked:
            return
        if self.radio1.Checked == True:
            self.textbox_RA.Enabled = True
            self.textbox_DEC.Enabled = True
            self.textbox_RA_std.Enabled = False
            self.textbox_RA_min.Enabled = False
            self.textbox_RA_sec.Enabled = False
            self.textbox_DEC_deg.Enabled = False
            self.textbox_DEC_min.Enabled = False
            self.textbox_DEC_sec.Enabled = False
            
        else:
            self.textbox_RA.Enabled = False
            self.textbox_DEC.Enabled = False
            self.textbox_RA_std.Enabled = True
            self.textbox_RA_min.Enabled = True
            self.textbox_RA_sec.Enabled = True
            self.textbox_DEC_deg.Enabled = True
            self.textbox_DEC_min.Enabled = True
            self.textbox_DEC_sec.Enabled = True

        
    def goto(self, sender, event):
		t = Telescope("ASCOM.Simulator.Telescope")
		if self.radio1.Checked == True:
			RA = float(self.textbox_RA.Text)
			DEC = float(self.textbox_DEC.Text)
		else:
			RA = float(self.textbox_RA_min.Text) / 60.0 + float(self.textbox_RA_sec.Text) / 3600.0
			RA = RA + float(self.textbox_RA_std.Text)
			DEC = abs(float(self.textbox_DEC_min.Text)) / 60.0 + abs(float(self.textbox_DEC_sec.Text)) / 3600.0
			DEC = DEC + abs(float(self.textbox_DEC_deg.Text))
			DEC = DEC * copysign(1, float(self.textbox_DEC_deg.Text))			
			
		print("GOTO to RA position : %f" % (RA))
		print("GOTO to DEC position: %f" % (DEC))
		print
		t.SlewToCoordinates(RA, DEC)

    def exit(self, sender, event):
    	print("Stop GOTO script")
        self.Close()
        
def launch_form():
    form = ChecksAndRadiosForm()
    form.StartPosition = FormStartPosition.CenterScreen
    form.Show()

GOTO_Custom_Button = SharpCap.AddCustomButton("GOTO", None, "GOTO", launch_form)
Any comments are welcome.

Regards,
Jean-Francois
Jean-Francois
Posts: 361
Joined: Sun Oct 13, 2019 10:52 am
Location: Germany

Re: Python Library Installation

#10

Post by Jean-Francois »

Hi Robin,

I have now a question ...

How can I command the GPS function of the QHY-174-GPS camera ?
- the LED on/off
- the LED Start Pos and End Pos values
- the imaging GPS time master/slave

Concerning the LED commands ... I think to write a script that performed the camera LED calibration automatically.
In the actual version of SharpCap, the LED Start Pos and End Poss are set automatically by SharpCap at each setting change (USB, binning, bit, ...).
(By the way, great job of reverse engineering)

But sometimes the values are not sufficient for "locking" the GPS.

My idea is ... what the user must do manually, the script can do it automatically.


Regards,
Jean-Francois
Post Reply