Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
gnthibault committed Aug 8, 2023
1 parent ce66682 commit 22009b3
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 73 deletions.
10 changes: 5 additions & 5 deletions Camera/IndiASICamera.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ def prepare_shoot(self):
# Always use maximum dynamic
dyn = self.get_dynamic()
max_dyn = self.get_maximum_dynamic()
if dyn != max_dyn:
if dyn < max_dyn:
self.logger.warning(f"Camera {self.name} using format {self.get_current_format()} with dynamic {dyn} although it "
f"is capable of {max_dyn}. Trying to set maximum bit depth")
self.set_switch("CCD_VIDEO_FORMAT", ["ASI_IMG_RAW16"])
self.logger.info(f"Now camera {self.name} has format {self.get_current_format()} allowing for dynamic "
f"{self.get_dynamic()}")
f"is capable of {max_dyn}.") #Trying to set maximum bit depth")
#self.set_switch("CCD_VIDEO_FORMAT", ["ASI_IMG_RAW16"])
#self.logger.info(f"Now camera {self.name} has format {self.get_current_format()} allowing for dynamic "
# f"{self.get_dynamic()}")

def get_current_format(self):
return [key for key, val in self.get_switch('CCD_VIDEO_FORMAT').items() if val == "On"]
Expand Down
7 changes: 3 additions & 4 deletions Camera/IndiCamera.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self, logger=None, config=None, connect_on_create=True):
camera_name='CCD Simulator',
pointing_seconds=30,
adjust_center_x=400,
adjust_center_y= 400,
adjust_center_y=400,
adjust_roi_search_size=50,
adjust_pointing_seconds=5,
autofocus_seconds=5,
Expand Down Expand Up @@ -310,10 +310,9 @@ def get_frame_type(self):

def set_frame_type(self, frame_type):
"""
FRAME_LIGHT Take a light fram mmmmmmmmmmmmmmmm bbb bnbn nb n b nb nb kllklke exposure
FRAME_LIGHT Take a light frame exposure
FRAME_BIAS Take a bias frame exposure
m, . ,m. ,mm m,,,,,,,,,,,, m,mmmmmmmmmmmmmmmmmmmmm mmm mm m mmmm mmmmmmmmmmFRAME_DARK Take a dark frame
exposure
FRAME_DARK Take a dark frame exposure
FRAME_FLAT Take a flat field frame exposure
"""
self.set_switch('CCD_FRAME_TYPE', [frame_type], sync=True, timeout=self.defaultTimeout)
Expand Down
7 changes: 4 additions & 3 deletions Manager/Manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,12 +530,12 @@ def close_observatory(self):

def unpark(self):
try:
# unpark the mount
self.mount.unpark()

# unpark the observatory
self.observatory.unpark()

# unpark the mount
self.mount.unpark()

# Launch guider server
if self.guider is not None:
self.guider.launch_server()
Expand Down Expand Up @@ -711,6 +711,7 @@ def _setup_cameras(self, **kwargs):
def setup_cameras():
try:
for cam_config in self.config["cameras"]:
self.logger.debug(f"Setting up camera with config {cam_config}")
cam_name = cam_config['module']
cam_module = load_module('Camera.'+cam_name)
cam = getattr(cam_module, cam_name)(
Expand Down
6 changes: 6 additions & 0 deletions Mount/IndiG11.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ def __init__(self, location, serv_time, config):
config=config,
connect_on_create=False)

def unpark(self):
if not self.is_connected():
self.initialize()
IndiAbstractMount.unpark(self)

def initialize(self):
self.connect()
self.set_startup_mode(mode='WARM_RESTART')
self.set_park_settings(mode='HOME')
Expand Down
107 changes: 78 additions & 29 deletions Observatory/AggregatedCustomScopeController.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Basic stuff
import json
import logging
import requests
import time
Expand Down Expand Up @@ -501,6 +502,14 @@ def __init__(self, config=None, connect_on_create=True):
Base.__init__(self)

self._is_initialized = False
# pin on arduino need to be configured either as input or ouput
# it means that we need to keep track of pin status internally
self.statuses = {
"scope_fan": False,
"scope_dew": False,
"finder_dew": False,
"mount_relay": False,
}

if config is None:
config = dict(
Expand Down Expand Up @@ -542,21 +551,12 @@ def __init__(self, config=None, connect_on_create=True):
if connect_on_create:
self.initialize()

# pin on arduino need to be configured either as input or ouput
# it means that we need to keep track of pin status internally
self.statuses = {
"scope_fan": False,
"scope_dew": False,
"finder_dew": False,
"mount_relay": False,
}

# Finished configuring
self.logger.debug('configured successfully')

def initialize(self):
# Restart all driver related to the aggregated devices
self.restart_all_drivers()
self.start_all_drivers()

# initialize upbv2
self.upbv2.initialize()
Expand All @@ -566,6 +566,9 @@ def initialize(self):
time.sleep(self._indi_driver_connect_delay_s)
self.arduino_servo_controller.initialize()

self.switch_on_instruments()
self.switch_on_mount()

self._is_initialized = True

def deinitialize(self):
Expand All @@ -575,6 +578,9 @@ def deinitialize(self):
"""
self.logger.debug("Deinitializing AggregatedCustomScopeController")

self.switch_off_mount()
self.switch_off_instruments()

# Deinitialize arduino servo first (as it relies on upb power)
self.arduino_servo_controller.deinitialize()

Expand All @@ -601,8 +607,15 @@ def close(self):
self.logger.debug("Closing AggregatedCustomScopeController")
self.close_finder_dustcap()
self.close_scope_dustcap()

def is_driver_started(self, driver_name):
return driver_name in self.get_running_driver_list()

def restart_driver(self, driver_name):
def get_running_driver_list(self):
running_driver_list = self.get_running_driver()
return [driver["name"] for driver in running_driver_list]

def get_running_driver(self):
"""
See documentation for the API here: https://github.com/knro/indiwebmanager
:param driver_name:
Expand All @@ -611,37 +624,75 @@ def restart_driver(self, driver_name):
try:
base_url = f"http://{self._indi_webserver_host}:"\
f"{self._indi_webserver_port}"
req = f"{base_url}/api/drivers/restart/"\
f"{urllib.parse.quote(driver_name)}"
response = requests.post(req)
self.logger.debug(f"restart_driver {driver_name} - url {req} - response: {response.text}")
req = f"{base_url}/api/server/drivers"
response = requests.get(req)
self.logger.debug(f"get_running_driver_list - url {req} - code {response.status_code} - response:{response.text}")
assert response.status_code == 200
running_driver_list = json.loads(response.text)
except json.JSONDecodeError as e:
msg = f"Cannot properly parse list of running indi driver from {response.text} : {e}"
self.logger.error(msg)
raise RuntimeError(msg)
except Exception as e:
self.logger.warning(f"Cannot restart indi driver : {e}")
msg = f"Cannot get list of running indi driver : {e}"
self.logger.error(msg)
raise RuntimeError(msg)
else:
return running_driver_list

def start_driver(self, driver_name):
def restart_driver(self, driver_name):
"""
See documentation for the API here: https://github.com/knro/indiwebmanager
:param driver_name:
:return:
"""
if self.is_driver_started(driver_name):
try:
base_url = f"http://{self._indi_webserver_host}:"\
f"{self._indi_webserver_port}"
req = f"{base_url}/api/drivers/restart/"\
f"{urllib.parse.quote(driver_name)}"
response = requests.post(req)
self.logger.debug(f"restart_driver {driver_name} - url {req} - code {response.status_code} - response:{response.text}")
assert response.status_code == 200
except Exception as e:
msg = f"Cannot restart indi driver : {e}"
self.logger.error(msg)
raise RuntimeError(msg)
else:
self.start_driver(driver_name, check_started=False)

def start_driver(self, driver_name, check_started=True):
"""
See documentation for the API here: https://github.com/knro/indiwebmanager
:param driver_name:
:return:
"""
if check_started and self.is_driver_started(driver_name):
return
try:
base_url = f"http://{self._indi_webserver_host}:"\
f"{self._indi_webserver_port}"
req = f"{base_url}/api/drivers/start/"\
f"{urllib.parse.quote(driver_name)}"
response = requests.post(req)
self.logger.debug(f"start_driver {driver_name} - url {req} - response: {response.text}")
self.logger.debug(f"start_driver {driver_name} - url {req} - code {response.status_code} - response:{response.text}")
assert response.status_code == 200
except Exception as e:
self.logger.warning(f"Cannot start indi driver : {e}")
msg = f"Cannot start indi driver : {e}"
self.logger.error(msg)
raise RuntimeError(msg)

def stop_driver(self, driver_name):
"""
See documentation for the API here: https://github.com/knro/indiwebmanager
:param driver_name:
:return:
"""
# No need to stop a driver that is not started
if not self.is_driver_started(driver_name):
self.logger.debug(f"No need to stop driver {driver_name} because it doesn't seems to be started")
return
try:
#if driver_name not in ["ZWO CCD"]: #"Shelyak SPOX", "Arduino telescope controller", "ASI EAF", "Altair", "ZWO CCD"
# return
Expand All @@ -650,16 +701,14 @@ def stop_driver(self, driver_name):
req = f"{base_url}/api/drivers/stop/"\
f"{urllib.parse.quote(driver_name)}"
#self.logger.setLevel("DEBUG")

#self.logger.warning(f"stop_driver {driver_name} DISABLED for now as it was randomly breaking indiserver")
response = requests.post(req)
self.logger.debug(f"stop_driver {driver_name} - url {req} - response: {response.text}")
assert response.status_code in [200, 500]
if response.status_code == 500:
self.logger.debug(f"stop_driver {driver_name} - url {req} - response: {response.text}, "
f"might be expected in case the driver was not started or already stopped")
self.logger.debug(f"stop_driver {driver_name} - url {req} - code {response.status_code} - response: {response.text}")
assert response.status_code == 200
except Exception as e:
self.logger.warning(f"Cannot stop indi driver : {e}")
msg = f"Cannot stop indi driver : {e}"
self.logger.error(msg)
raise RuntimeError(msg)

def switch_on_instruments(self):
""" blocking call: switch on cameras, calibration tools, finderscopes, etc...
Expand All @@ -682,10 +731,10 @@ def switch_off_instruments(self):
for driver_name in self._indi_resetable_instruments_driver_name_list.values():
self.stop_driver(driver_name)

def restart_all_drivers(self):
def start_all_drivers(self):
for driver_name in self._indi_resetable_instruments_driver_name_list.values():
self.restart_driver(driver_name)
self.restart_driver(self._indi_mount_driver_name)
self.start_driver(driver_name, check_started=True)
self.start_driver(self._indi_mount_driver_name, check_started=True)

def stop_all_drivers(self):
for driver_name in self._indi_resetable_instruments_driver_name_list.values():
Expand Down
51 changes: 36 additions & 15 deletions Spectro/IndiSpectroController.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,22 @@

class IndiSpectroController(IndiDevice):
"""
Return of indi_getprop -p 7625 "Shelyak Spox.*.*"
Shelyak Spox.CONNECTION.CONNECT=On
Shelyak Spox.CONNECTION.DISCONNECT=Off
Shelyak Spox.DRIVER_INFO.DRIVER_NAME=Shelyak Spox
Shelyak Spox.DRIVER_INFO.DRIVER_EXEC=indi_shelyakspox_spectrograph
Shelyak Spox.DRIVER_INFO.DRIVER_VERSION=1.0
Shelyak Spox.DRIVER_INFO.DRIVER_INTERFACE=0
Shelyak Spox.CONFIG_PROCESS.CONFIG_LOAD=Off
Shelyak Spox.CONFIG_PROCESS.CONFIG_SAVE=Off
Shelyak Spox.CONFIG_PROCESS.CONFIG_DEFAULT=Off
Shelyak Spox.CONFIG_PROCESS.CONFIG_PURGE=Off
Shelyak Spox.DEVICE_PORT.PORT=/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AD0JE0ID-if00-port0
Shelyak Spox.CALIBRATION.DARK=Off
Shelyak Spox.CALIBRATION.FLAT=Off
Shelyak Spox.CALIBRATION.CALIBRATION=Off
Shelyak Spox.CALIBRATION.SKY=Off
"""
def __init__(self,
config=None,
Expand All @@ -21,11 +36,11 @@ def __init__(self,
if config is None:
config = dict(
module="IndiSpectroController",
device_name="spox",
port="/dev/ttyUSB0",
device_name="Shelyak Spox",
port="/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AD0JE0ID-if00-port0",
indi_client=dict(
indi_host="localhost",
indi_port="7624"
indi_port="7625"
))

self.port = config['port']
Expand All @@ -41,42 +56,48 @@ def __init__(self,
self.logger.debug('Indi spectro controller configured successfully')

def initialize(self):
self._setup_indi_client()
self.connect_client()
self.connect(connect_device=False) #TODO TN Urgent check if this is ok
self.set_port()
self.connect_device()
self.initialize_calibration()

def set_port(self):
self.set_text("DEVICE_PORT", {"PORT": self.port})

def initialize_calibration(self):
self.open_optical_path()

def on_emergency(self):
self.logger.debug("Indi spectro controller: on emergency routine started...")
self.switch_off_spectro_light()
self.switch_off_flat_light()
self.open_optical_path()
self.logger.debug("Indi spectro controller: on emergency routine finished")

def switch_on_spectro_light(self):
self.logger("Switching-on spectro light")
self.set_switch("CALIBRATION", ["CALIBRATION"])
self.logger.debug("Switching-on spectro light")

def switch_off_spectro_light(self):
self.logger("Switching-off spectro light")
self.logger.debug("Switching-off spectro light")
self.open_optical_path()

def switch_on_flat_light(self):
self.logger("Switching-on flat light")
self.set_switch("CALIBRATION", ["FLAT"])
self.logger.debug("Switching-on flat light")

def switch_off_flat_light(self):
self.logger("Switching-off flat light")
self.logger.debug("Switching-off flat light")
self.open_optical_path()

def close_optical_path_for_dark(self):
self.logger("Close optical path for dark")
self.set_switch("CALIBRATION", ["DARK"])
self.logger.debug("Close optical path for dark")

def open_optical_path(self):
self.logger("Open optical path")
self.set_switch("CALIBRATION", ["SKY"])
self.logger.debug("Open optical path")

def __str__(self):
return f"Spectro controller: {self.device_name}"
return f"Spectro controller: {self.device_name} with current calibration {self.get_switch('CALIBRATION')}"

def __repr__(self):
return self.__str__()
Loading

0 comments on commit 22009b3

Please sign in to comment.