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 3416c20 commit 72fe2e6
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 35 deletions.
6 changes: 6 additions & 0 deletions Camera/AbstractCamera.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ def uid(self):
# Methods
###############################################################################

def park(self):
self.logger.debug(f"Parking camera {self.camera_name}")

def unpark(self):
self.logger.debug(f"Unparking camera {self.camera_name}")

def take_observation(self, observation, headers=None, filename=None,
*args, **kwargs):
"""Take an observation
Expand Down
8 changes: 8 additions & 0 deletions Camera/IndiAbstractCamera.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ def __init__(self, serv_time, config=None, connect_on_create=True):
self.indi_camera_config = config


def park(self):
self.logger.debug(f"Parking camera {self.camera_name}")
self.disconnect()

def unpark(self):
self.logger.debug(f"Unparking camera {self.camera_name}")
self.connect(connect_device=True)

# TODO TN: setup event based acquisition properly
def shoot_asyncWithEvent(self, exp_time_sec, filename, exposure_event,
**kwargs):
Expand Down
18 changes: 15 additions & 3 deletions Manager/Manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,11 +531,16 @@ def close_observatory(self):
def unpark(self):
try:
# unpark the observatory
self.observatory.power_all_equipments()
self.observatory.unpark()

# unpark the mount
self.mount.unpark()

# unpark cameras
for camera_name, camera in self.cameras.items():
camera.unpark()

# Launch guider server
if self.guider is not None:
self.guider.launch_server()
Expand All @@ -554,11 +559,16 @@ def park(self):
self.guider.disconnect_profile()
self.guider.disconnect_server()

# unpark cameras
for camera_name, camera in self.cameras.items():
camera.unpark()

# park the mount
self.mount.park()

# park the observatory
self.observatory.park()
self.observatory.shutdown_equipments()

return True
except Exception as e:
Expand Down Expand Up @@ -654,7 +664,9 @@ def _setup_mount(self):
self.mount = getattr(mount_module, mount_name)(
location=self.earth_location,
serv_time=self.serv_time,
config=self.config['mount'])
config=self.config['mount'],
connect_on_create=False
)
except Exception as e:
self.logger.error(f"Cannot load mount module: {e}")
raise error.MountNotFound(f"Problem setting up mount")
Expand Down Expand Up @@ -717,8 +729,8 @@ def setup_cameras():
cam = getattr(cam_module, cam_name)(
serv_time=self.serv_time,
config=cam_config,
connect_on_create=True)
cam.prepare_shoot()
connect_on_create=False)
#cam.prepare_shoot()
self.cameras[cam.name] = cam
except Exception as e:
raise RuntimeError(f"Problem setting up camera: {e}")
Expand Down
2 changes: 2 additions & 0 deletions Mount/IndiAbstractMount.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def park(self):
try:
IndiMount.park(self)
self._is_parked = True
self.disconnect() # Disconnect indi server
except Exception as e:
self.logger.warning('Problem with park')
# by default, we assume that mount is in the "worst" situation
Expand All @@ -125,6 +126,7 @@ def unpark(self):
"""
IndiMount.unpark(self)
self._is_parked = False
self.connect(connect_device=True) #

def slew_to_coord(self, coord):
IndiMount.slew_to_coord_and_track(self, coord)
Expand Down
4 changes: 2 additions & 2 deletions Mount/IndiG11.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,15 +215,15 @@ class IndiG11(IndiAbstractMount):
Losmandy Gemini.STARTUP_MODE.WARM_RESTART=Off
"""

def __init__(self, location, serv_time, config):
def __init__(self, location, serv_time, config, connect_on_create=False):

if config is None:
config = dict(mount_name="Losmandy Gemini")

super().__init__(location=location,
serv_time=serv_time,
config=config,
connect_on_create=False)
connect_on_create=connect_on_create)

def unpark(self):
if not self.is_connected():
Expand Down
53 changes: 34 additions & 19 deletions Observatory/AggregatedCustomScopeController.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from Base.Base import Base
from helper.IndiDevice import IndiDevice
from utils.error import ScopeControllerError

from utils.error import IndiClientPredicateTimeoutError

class UPBV2(IndiDevice, Base):
"""
Expand Down Expand Up @@ -516,24 +516,23 @@ def __init__(self, config=None, connect_on_create=True):
config_upbv2=None,
config_arduino=None,
indi_driver_connect_delay_s=10,
indi_resetable_instruments_driver_name_list=dict(
driver_1="ZWO CCD ASI290MM Mini",
driver_2="Altair AA183MPRO",
driver_3="Shelyak SPOX",
driver_4="PlayerOne CCD Ares-M PRO",
driver_5="Arduino",
driver_6="Losmandy Gemini"
),
indi_resetable_instruments_driver_map={
"ZWO CCD": "ZWO CCD ASI290MM Mini",
"Altair": "Altair AA183MPRO",
"Shelyak SPOX": "Shelyak SPOX",
"PlayerOne CCD": "PlayerOne CCD Ares-M PRO",
"Arduino telescope controller": "Arduino"
},
indi_mount_driver_name="Losmandy Gemini",
indi_webserver_host="localhost",
indi_webserver_port="8624",)
indi_webserver_port="8624")

# Actual device config
self.config_upbv2 = config["config_upbv2"]
self.config_arduino = config["config_arduino"]

# Local features
self._indi_resetable_instruments_driver_name_list = config["indi_resetable_instruments_driver_name_list"]
self._indi_resetable_instruments_driver_map = config["indi_resetable_instruments_driver_map"]
self._indi_driver_connect_delay_s = config["indi_driver_connect_delay_s"]
self._indi_mount_driver_name = config["indi_mount_driver_name"]
self._indi_webserver_host = config["indi_webserver_host"]
Expand All @@ -554,7 +553,7 @@ def __init__(self, config=None, connect_on_create=True):
# Finished configuring
self.logger.debug('configured successfully')

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

Expand All @@ -571,7 +570,7 @@ def initialize(self):

self._is_initialized = True

def deinitialize(self):
def power_off_all_equipments(self):
"""
:return:
Expand Down Expand Up @@ -607,7 +606,20 @@ def close(self):
self.logger.debug("Closing AggregatedCustomScopeController")
self.close_finder_dustcap()
self.close_scope_dustcap()


def probe_device_driver_connection(self, driver_name, device_name):
probe = IndiDevice(
device_name=device_name,
indi_client_config=self.config["indi_client"])
# setup indi client
probe.connect(connect_device=False)
try:
probe.wait_for_any_property_vectors(timeout=5)
except IndiClientPredicateTimeoutError as e:
return False
else:
return True

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

Expand Down Expand Up @@ -714,30 +726,33 @@ def switch_on_instruments(self):
""" blocking call: switch on cameras, calibration tools, finderscopes, etc...
We also need to load the corresponding indi driver
"""
if not self._is_initialized:
self.initialize()
self.logger.debug("Switching on all instruments")
self.upbv2.power_on_all_telescope_equipments()

# Now we need to wait a bit before trying to connect driver
# but _indi_driver_connect_delay_s was already waited for at previous step
for driver_name in self._indi_resetable_instruments_driver_name_list.values():
self.restart_driver(driver_name)
for driver_name, device_name in self._indi_resetable_instruments_driver_map.items():
if not self.probe_device_driver_connection(driver_name=driver_name, device_name=device_name):
self.restart_driver(driver_name)

def switch_off_instruments(self):
""" blocking call: switch off camera
"""
self.logger.debug("Switching off all equipments connected to upbv2")

self.upbv2.power_off_all_telescope_equipments()
for driver_name in self._indi_resetable_instruments_driver_name_list.values():
for driver_name, device_name in self._indi_resetable_instruments_driver_map.items():
self.stop_driver(driver_name)

def start_all_drivers(self):
for driver_name in self._indi_resetable_instruments_driver_name_list.values():
for driver_name, device_name in self._indi_resetable_instruments_driver_map.items():
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():
for driver_name, device_name in self._indi_resetable_instruments_driver_map.items():
self.stop_driver(driver_name)
self.stop_driver(self._indi_mount_driver_name)

Expand Down
12 changes: 10 additions & 2 deletions Observatory/Observatory.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,21 @@ def has_scope(self):

def park(self):
self.logger.debug('Observatory: parking scope')
self.open_everything()

def shutdown_equipments(self):
self.logger.debug('Observatory: shutting down all scope equipments')
if self.has_scope:
self.scope_controller.close()
self.scope_controller.power_off_all_equipments()

def unpark(self):
self.logger.debug('Observatory: unparking scope')
self.close_everything()

def power_all_equipments(self):
self.logger.debug('Observatory: powering all scope equipments')
if self.has_scope:
self.scope_controller.open()
self.scope_controller.power_all_equipments()

def open_everything(self):
try:
Expand Down
24 changes: 23 additions & 1 deletion apps/prototyping/Camera/IndiASICameraDriverTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
from Camera.IndiASICamera import IndiASICamera
from Service.NTPTimeService import HostTimeService

# Local
from utils.error import IndiClientPredicateTimeoutError

if __name__ == '__main__':
config = dict(
camera_name='ZWO CCD ASI120MC',
Expand Down Expand Up @@ -50,7 +53,26 @@
probe = IndiDevice(
device_name=config["camera_name"],
indi_client_config=config["indi_client"])
pass
# setup indi client
probe.connect(connect_device=False)
try:
probe.wait_for_any_property_vectors(timeout=5)
except IndiClientPredicateTimeoutError as e:
print(f"There was an error: {e}")
assert bool(probe.property_vectors)
print("test")















Expand Down
12 changes: 6 additions & 6 deletions conf_files/config_backyard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ observatory:
indi_host: localhost
indi_port: 7625
indi_driver_connect_delay_s: 10
indi_resetable_instruments_driver_name_list:
driver_1: ZWO CCD
driver_2: Altair
driver_3: Shelyak SPOX
driver_4: PlayerOne CCD
driver_5: Arduino telescope controller
indi_resetable_instruments_driver_map:
ZWO CCD: ZWO CCD ASI290MM Mini
Altair: Altair AA183MPRO
Shelyak SPOX: Shelyak SPOX
PlayerOne CCD: PlayerOne CCD Ares-M PRO
Arduino telescope controller: Arduino
indi_mount_driver_name: Losmandy Gemini
indi_webserver_host: localhost
indi_webserver_port: 8624
Expand Down
6 changes: 4 additions & 2 deletions helper/IndiClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

# Indi stuff
from helper.client import INDIClient
from utils.error import IndiClientPredicateTimeoutError

# Imaging and Fits stuff
from astropy.io import fits
Expand Down Expand Up @@ -130,9 +131,10 @@ def sync_with_predicate(self, predicate_checker, timeout=30):
try:
assert (future.result(timeout) is True)
except concurrent.futures.TimeoutError:
logger.error(f"Waiting for predicate {predicate_checker} took too long...")
msg = f"Waiting for predicate {predicate_checker} took too long..."
logger.error(msg)
future.cancel()
raise RuntimeError
raise IndiClientPredicateTimeoutError(msg)
except Exception as exc:
logger.error(f"Error while trying to wait for predicate: {exc!r}")
raise RuntimeError
Expand Down
10 changes: 10 additions & 0 deletions helper/IndiDevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,14 @@ def wait_for_vector_light(self, vector_name, timeout=None):
def wait_for_incoming_blob_vector(self, blob_vector_name=None, timeout=None):
blob_checker = lambda: self.check_blob_vector(blob_vector_name)
self.indi_client.sync_with_predicate(blob_checker, timeout=timeout)
return

def wait_for_any_property_vectors(self, timeout=5):
"""
Wait until property vector is non-empty
:param timeout:
:return:
"""
light_checker = lambda: bool(self.property_vectors)
self.indi_client.sync_with_predicate(light_checker, timeout=timeout)
return
5 changes: 5 additions & 0 deletions utils/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class ImageAcquisitionError(Error):
def __init(self, message="Error while camera is trying to acquire an image"):
super().__init__(message)

class IndiClientPredicateTimeoutError(Error):
""" Error while trying to acquire image """
def __init(self, message="Error while camwaiting a predicate"):
super().__init__(message)

class BLOBError(Error):
""" Error for Indi Blob communication problem """
def __init(self, message="Indi BLOB Error"):
Expand Down

0 comments on commit 72fe2e6

Please sign in to comment.