From d843e3343436e9895bec6dee43d798fce8c6bde5 Mon Sep 17 00:00:00 2001 From: Etienne Pallier Date: Wed, 23 Oct 2019 16:14:16 +0200 Subject: [PATCH] renommé base.py en device_controller.py (plus clair) --- src/core/pyros_django/agent/AgentDevice.py | 2 +- src/core/pyros_django/common/models.py | 2 +- src/core/pyros_django/common/models_ORIG.py | 425 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/core/pyros_django/majordome/doc/AgentMajordome_object_diag.pu | 20 ++++++++++---------- src/device_controller/abstract_component/base.py | 725 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/device_controller/abstract_component/detector_sensor.py | 2 +- src/device_controller/abstract_component/detector_shutter.py | 2 +- src/device_controller/abstract_component/device_controller.py | 725 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/device_controller/abstract_component/filter_selector.py | 2 +- src/device_controller/abstract_component/telescope.py | 2 +- src/device_controller/concrete_component/gemini/client_telescope_gemini_controller_run.py | 2 +- src/device_controller/concrete_component/gemini/gemini_telescope_controller.py | 2 +- src/device_controller/concrete_component/sbig/sbig_controller.py | 2 +- src/device_controller/concrete_component/sbig/sbig_detector_sensor_controller.py | 2 +- src/device_controller/concrete_component/sbig/sbig_detector_shutter_controller.py | 2 +- src/device_controller/concrete_component/sbig/sbig_filter_selector_controller.py | 2 +- 16 files changed, 747 insertions(+), 1172 deletions(-) delete mode 100644 src/core/pyros_django/common/models_ORIG.py delete mode 100755 src/device_controller/abstract_component/base.py create mode 100755 src/device_controller/abstract_component/device_controller.py diff --git a/src/core/pyros_django/agent/AgentDevice.py b/src/core/pyros_django/agent/AgentDevice.py index ce3e1f2..76f3411 100755 --- a/src/core/pyros_django/agent/AgentDevice.py +++ b/src/core/pyros_django/agent/AgentDevice.py @@ -13,7 +13,7 @@ from common.models import AgentDeviceStatus, Command, get_or_create_unique_row_f sys.path.append("../../..") -from device_controller.abstract_component.base import DeviceControllerAbstract +from device_controller.abstract_component.device_controller import DeviceControllerAbstract ##log = L.setupLogger("AgentXTaskLogger", "AgentX") diff --git a/src/core/pyros_django/common/models.py b/src/core/pyros_django/common/models.py index 307d0a3..bb3b81f 100644 --- a/src/core/pyros_django/common/models.py +++ b/src/core/pyros_django/common/models.py @@ -13,7 +13,7 @@ from model_utils import Choices # DeviceCommand is used by class Command import sys sys.path.append("../../..") -from src.device_controller.abstract_component.base import DeviceCommand +from src.device_controller.abstract_component.device_controller import DeviceCommand ''' NOT USED - to be removed diff --git a/src/core/pyros_django/common/models_ORIG.py b/src/core/pyros_django/common/models_ORIG.py deleted file mode 100644 index 20d6e6b..0000000 --- a/src/core/pyros_django/common/models_ORIG.py +++ /dev/null @@ -1,425 +0,0 @@ -# This is an auto-generated Django model module. -# You'll have to do the following manually to clean this up: -# * Rearrange models' order -# * Make sure each model has one field with primary_key=True -# * Make sure each ForeignKey has `on_delete` set to the desired behavior. -# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table -# Feel free to rename the models, but don't rename db_table values or -# field names. -from __future__ import unicode_literals - -from django.db import models - - -class Album(models.Model): - sequence = models.ForeignKey('Sequence', models.DO_NOTHING) - detector = models.ForeignKey('Detector', models.DO_NOTHING) - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - created = models.DateTimeField(blank=True, null=True) - updated = models.DateTimeField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'album' - - -class Alert(models.Model): - request = models.ForeignKey('Request', models.DO_NOTHING) - strategyobs = models.ForeignKey('Strategyobs', models.DO_NOTHING) - voevent_xml = models.TextField(blank=True, null=True) - type = models.CharField(max_length=45, blank=True, null=True) - client = models.CharField(max_length=45, blank=True, null=True) - burst_jd = models.CharField(max_length=45, blank=True, null=True) - burst_ra = models.CharField(max_length=45, blank=True, null=True) - burst_dec = models.CharField(max_length=45, blank=True, null=True) - equinox = models.CharField(max_length=45, blank=True, null=True) - jd_pkt = models.IntegerField(blank=True, null=True) - jd_send = models.IntegerField(blank=True, null=True) - jd_received = models.IntegerField(blank=True, null=True) - trigger_instrum = models.CharField(max_length=45, blank=True, null=True) - trigger_num = models.CharField(max_length=45, blank=True, null=True) - grb_error = models.CharField(max_length=45, blank=True, null=True) - def_not_grb = models.IntegerField(blank=True, null=True) - editor = models.CharField(max_length=45, blank=True, null=True) - flag = models.CharField(max_length=45, blank=True, null=True) - idgcn_notice = models.IntegerField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'alert' - - -class Country(models.Model): - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - quota = models.FloatField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'country' - - -class Detector(models.Model): - device = models.ForeignKey('Device', models.DO_NOTHING) - telescope = models.ForeignKey('Telescope', models.DO_NOTHING) - status = models.CharField(max_length=7, blank=True, null=True) - nb_photo_x = models.IntegerField(blank=True, null=True) - nb_photo_y = models.IntegerField(blank=True, null=True) - photo_size_x = models.IntegerField(blank=True, null=True) - photo_size_y = models.IntegerField(blank=True, null=True) - has_shutter = models.IntegerField(blank=True, null=True) - equivalent_foc_len = models.CharField(max_length=45, blank=True, null=True) - acq_start = models.DateTimeField(blank=True, null=True) - acq_stop = models.DateTimeField(blank=True, null=True) - check_temp = models.FloatField(blank=True, null=True) - gain = models.FloatField(blank=True, null=True) - readout_noise = models.FloatField(blank=True, null=True) - readout_time = models.FloatField(blank=True, null=True) - idcam_readout_mode = models.IntegerField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'detector' - - -class Device(models.Model): - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - created = models.DateTimeField(blank=True, null=True) - updated = models.DateTimeField(blank=True, null=True) - is_online = models.IntegerField(blank=True, null=True) - status = models.CharField(max_length=11, blank=True, null=True) - maintenance_date = models.DateTimeField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'device' - - -class Filter(models.Model): - device = models.ForeignKey(Device, models.DO_NOTHING) - detector = models.ForeignKey(Detector, models.DO_NOTHING) - category = models.CharField(max_length=1, blank=True, null=True) - transmission_curve_doc = models.CharField( - max_length=45, blank=True, null=True) - - class Meta: - managed = False - db_table = 'filter' - - -class Image(models.Model): - plan = models.ForeignKey('Plan', models.DO_NOTHING) - nrtanalysis = models.ForeignKey( - 'Nrtanalysis', models.DO_NOTHING, blank=True, null=True) - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - created = models.DateTimeField(blank=True, null=True) - updated = models.DateTimeField(blank=True, null=True) - date_from_gps = models.CharField(max_length=45, blank=True, null=True) - level = models.IntegerField(blank=True, null=True) - type = models.CharField(max_length=5, blank=True, null=True) - quality = models.CharField(max_length=45, blank=True, null=True) - flaggps = models.CharField(max_length=45, blank=True, null=True) - exposure = models.CharField(max_length=45, blank=True, null=True) - tempext = models.CharField(max_length=45, blank=True, null=True) - pressure = models.CharField(max_length=45, blank=True, null=True) - humidext = models.CharField(max_length=45, blank=True, null=True) - wind = models.CharField(max_length=45, blank=True, null=True) - wind_dir = models.CharField(max_length=45, blank=True, null=True) - dwnimg = models.CharField(max_length=45, blank=True, null=True) - dwncata = models.CharField(max_length=45, blank=True, null=True) - dwn = models.CharField(max_length=45, blank=True, null=True) - level0_fits_name = models.CharField(max_length=45, blank=True, null=True) - level1a_fits_name = models.CharField(max_length=45, blank=True, null=True) - level1b_fits_name = models.CharField(max_length=45, blank=True, null=True) - - class Meta: - managed = False - db_table = 'image' - - -class Nrtanalysis(models.Model): - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - created = models.DateTimeField(blank=True, null=True) - updated = models.DateTimeField(blank=True, null=True) - analysis = models.TextField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'nrtanalysis' - - -class Plan(models.Model): - album = models.ForeignKey(Album, models.DO_NOTHING) - filter = models.ForeignKey(Filter, models.DO_NOTHING) - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.CharField(max_length=45, blank=True, null=True) - created = models.DateTimeField(blank=True, null=True) - updated = models.DateTimeField(blank=True, null=True) - duration = models.FloatField(blank=True, null=True) - position = models.CharField(max_length=45, blank=True, null=True) - exposure_time = models.FloatField(blank=True, null=True) - nb_images = models.IntegerField(blank=True, null=True) - dithering = models.IntegerField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'plan' - - -class Request(models.Model): - user = models.ForeignKey('User', models.DO_NOTHING) - scientificprogram = models.ForeignKey( - 'Scientificprogram', models.DO_NOTHING) - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - created = models.DateTimeField(blank=True, null=True) - updated = models.DateTimeField(blank=True, null=True) - is_alert = models.IntegerField(blank=True, null=True) - type = models.CharField(max_length=8, blank=True, null=True) - status = models.CharField(max_length=10, blank=True, null=True) - target_or_theme = models.CharField(max_length=45, blank=True, null=True) - priority = models.IntegerField(blank=True, null=True) - autodeposit = models.IntegerField(blank=True, null=True) - checkpoint = models.CharField(max_length=45, blank=True, null=True) - flag = models.CharField(max_length=45, blank=True, null=True) - - class Meta: - managed = False - db_table = 'request' - - -class Schedule(models.Model): - created = models.DateTimeField(blank=True, null=True) - day_start = models.DateTimeField(blank=True, null=True) - day_stop = models.DateTimeField(blank=True, null=True) - flag = models.CharField(max_length=45, blank=True, null=True) - - class Meta: - managed = False - db_table = 'schedule' - - -class ScheduleHasSequences(models.Model): - schedulehistory = models.ForeignKey('Schedulehistory', models.DO_NOTHING) - sequence = models.ForeignKey('Sequence', models.DO_NOTHING) - - class Meta: - managed = False - db_table = 'schedule_has_sequences' - unique_together = (('schedulehistory', 'sequence'),) - - -class Schedulehistory(models.Model): - created = models.DateTimeField(blank=True, null=True) - day_start = models.DateTimeField(blank=True, null=True) - day_stop = models.DateTimeField(blank=True, null=True) - flag = models.CharField(max_length=45, blank=True, null=True) - - class Meta: - managed = False - db_table = 'schedulehistory' - - -class Scientificprogram(models.Model): - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - quota = models.FloatField(blank=True, null=True) - priority = models.IntegerField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'scientificprogram' - - -class Sequence(models.Model): - request = models.ForeignKey(Request, models.DO_NOTHING) - sequencetype = models.ForeignKey('Sequencetype', models.DO_NOTHING) - schedule = models.ForeignKey(Schedule, models.DO_NOTHING) - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - created = models.DateTimeField(blank=True, null=True) - updated = models.DateTimeField(blank=True, null=True) - is_alert = models.IntegerField(blank=True, null=True) - status = models.CharField(max_length=11, blank=True, null=True) - duration = models.FloatField(blank=True, null=True) - pointing = models.CharField(max_length=45, blank=True, null=True) - with_drift = models.IntegerField(blank=True, null=True) - priority = models.IntegerField(blank=True, null=True) - analysis_method = models.CharField(max_length=45, blank=True, null=True) - exec_start = models.DateTimeField() - exec_stop = models.DateTimeField(blank=True, null=True) - moon_min = models.IntegerField(blank=True, null=True) - alt_min = models.IntegerField(blank=True, null=True) - type = models.CharField(max_length=6, blank=True, null=True) - img_current = models.CharField(max_length=45, blank=True, null=True) - img_total = models.CharField(max_length=45, blank=True, null=True) - not_obs = models.IntegerField(blank=True, null=True) - obsolete = models.IntegerField(blank=True, null=True) - processing = models.IntegerField(blank=True, null=True) - flag = models.CharField(max_length=45, blank=True, null=True) - - class Meta: - managed = False - db_table = 'sequence' - - -class Sequencetype(models.Model): - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - priority = models.IntegerField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'sequencetype' - - -class Sitewatch(models.Model): - updated = models.DateTimeField(blank=True, null=True) - lights = models.CharField(max_length=45, blank=True, null=True) - dome = models.CharField(max_length=45, blank=True, null=True) - doors = models.CharField(max_length=45, blank=True, null=True) - temperature = models.FloatField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'sitewatch' - - -class Sitewatchhistory(models.Model): - id = models.IntegerField(primary_key=True) - - class Meta: - managed = False - db_table = 'sitewatchhistory' - - -class Strategyobs(models.Model): - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - json_file = models.CharField(max_length=45, blank=True, null=True) - - class Meta: - managed = False - db_table = 'strategyobs' - - -class Telescope(models.Model): - device = models.ForeignKey(Device, models.DO_NOTHING) - mount_type = models.CharField(max_length=9, blank=True, null=True) - diameter = models.FloatField(blank=True, null=True) - status = models.CharField(max_length=45, blank=True, null=True) - latitude = models.FloatField(blank=True, null=True) - longitude = models.FloatField(blank=True, null=True) - sens = models.CharField(max_length=1, blank=True, null=True) - altitude = models.FloatField(blank=True, null=True) - readout_time = models.IntegerField(blank=True, null=True) - slew_time = models.IntegerField(blank=True, null=True) - slew_dead = models.IntegerField(blank=True, null=True) - slew_rate_max = models.FloatField(blank=True, null=True) - horizon_type = models.CharField(max_length=45, blank=True, null=True) - horizon_def = models.FloatField(blank=True, null=True) - lim_dec_max = models.FloatField(blank=True, null=True) - lim_dec_min = models.FloatField(blank=True, null=True) - lim_ha_rise = models.FloatField(blank=True, null=True) - lim_ha_set = models.FloatField(blank=True, null=True) - address = models.CharField(max_length=45, blank=True, null=True) - night_elev_sun = models.FloatField(blank=True, null=True) - mpc_code = models.CharField(max_length=45, blank=True, null=True) - - class Meta: - managed = False - db_table = 'telescope' - - -class User(models.Model): - country = models.ForeignKey(Country, models.DO_NOTHING) - userlevel = models.ForeignKey('Userlevel', models.DO_NOTHING) - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - created = models.DateTimeField(blank=True, null=True) - updated = models.DateTimeField(blank=True, null=True) - firstname = models.CharField(max_length=45, blank=True, null=True) - email = models.CharField(max_length=45, blank=True, null=True) - url = models.CharField(max_length=45, blank=True, null=True) - tel1 = models.CharField(max_length=45, blank=True, null=True) - tel2 = models.CharField(max_length=45, blank=True, null=True) - address = models.CharField(max_length=45, blank=True, null=True) - login = models.CharField(max_length=15, blank=True, null=True) - # Field renamed because it was a Python reserved word. - pass_field = models.CharField( - db_column='pass', max_length=45, blank=True, null=True) - last_connect = models.DateTimeField(blank=True, null=True) - cur_connect = models.DateTimeField(blank=True, null=True) - putvalid_beg = models.DateTimeField(blank=True, null=True) - putvalid_end = models.DateTimeField(blank=True, null=True) - acqvalid_beg = models.CharField(max_length=45, blank=True, null=True) - acqvalid_end = models.CharField(max_length=45, blank=True, null=True) - quota = models.FloatField(blank=True, null=True) - quota_rea = models.FloatField(blank=True, null=True) - u_priority = models.IntegerField(blank=True, null=True) - p_priority = models.IntegerField(blank=True, null=True) - dir_level = models.IntegerField(blank=True, null=True) - can_del_void_req = models.IntegerField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'user' - - -class UserHasScientificprograms(models.Model): - user = models.ForeignKey(User, models.DO_NOTHING) - scientificprogram = models.ForeignKey(Scientificprogram, models.DO_NOTHING) - - class Meta: - managed = False - db_table = 'user_has_scientificprograms' - unique_together = (('user', 'scientificprogram'),) - - -class Userlevel(models.Model): - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - priority = models.IntegerField(blank=True, null=True) - quota = models.FloatField(blank=True, null=True) - - class Meta: - managed = False - db_table = 'userlevel' - - -class Weatherwatch(models.Model): - updated = models.DateTimeField(blank=True, null=True) - humid_int = models.FloatField(blank=True, null=True) - humid_ext = models.FloatField(blank=True, null=True) - wind = models.FloatField(blank=True, null=True) - wind_dir = models.CharField(max_length=1, blank=True, null=True) - temp_int = models.FloatField(blank=True, null=True) - temp_ext = models.FloatField(blank=True, null=True) - pressure = models.FloatField(blank=True, null=True) - rain = models.FloatField(blank=True, null=True) - dwn = models.CharField(max_length=45, blank=True, null=True) - - class Meta: - managed = False - db_table = 'weatherwatch' - - -class Weatherwatchhistory(models.Model): - datetime = models.DateTimeField(blank=True, null=True) - humid_int = models.CharField(max_length=45, blank=True, null=True) - humid_ext = models.CharField(max_length=45, blank=True, null=True) - wind = models.CharField(max_length=45, blank=True, null=True) - wind_dir = models.CharField(max_length=45, blank=True, null=True) - temp_int = models.CharField(max_length=45, blank=True, null=True) - temp_ext = models.CharField(max_length=45, blank=True, null=True) - pressure = models.CharField(max_length=45, blank=True, null=True) - rain = models.CharField(max_length=45, blank=True, null=True) - dwn = models.CharField(max_length=45, blank=True, null=True) - - class Meta: - managed = False - db_table = 'weatherwatchhistory' diff --git a/src/core/pyros_django/majordome/doc/AgentMajordome_object_diag.pu b/src/core/pyros_django/majordome/doc/AgentMajordome_object_diag.pu index e19030e..bee672f 100755 --- a/src/core/pyros_django/majordome/doc/AgentMajordome_object_diag.pu +++ b/src/core/pyros_django/majordome/doc/AgentMajordome_object_diag.pu @@ -89,18 +89,18 @@ ClientChannel <|-- ClientChannelUSB /' ======= GEMINI controllers (& sim) ======= '/ -class AD_TelescopeGemini #lightblue -AD_TelescopeGemini -u--|> AgentDevice +class AgentDeviceTelescopeGemini #lightblue +AgentDeviceTelescopeGemini -u--|> AgentDevice /' Components (only 1) '/ -AD_Telescope1 -d-> AD_TelescopeGemini :alias of +AD_Telescope1 -d-> AgentDeviceTelescopeGemini :alias of class DC_Gemini <> #lightblue class DC_MountGemini #lightblue class DS_Gemini #lightblue /'DC_Mount o-left- DS_Mount'/ -AD_TelescopeGemini --> DC_Gemini :use +AgentDeviceTelescopeGemini --> DC_Gemini :use /'DC_Gemini o-left- DS_Gemini'/ /' Controllers '/ @@ -120,13 +120,13 @@ DS_Mount --|> DeviceSimulator /' ======= SBIG controllers (& sim) ======= '/ -class AD_SBIG <> #lightgreen -AD_SBIG -u--|> AgentDevice +class AgentDeviceSBIG <> #lightgreen +AgentDeviceSBIG -u--|> AgentDevice /' Components (3) '/ -AD_FilterSelector1 --> AD_SBIG :alias of -AD_Shutter1 --> AD_SBIG :alias of -AD_Sensor1 --> AD_SBIG :alias of +AD_FilterSelector1 --> AgentDeviceSBIG :alias of +AD_Shutter1 --> AgentDeviceSBIG :alias of +AD_Sensor1 --> AgentDeviceSBIG :alias of class DC_SBIG <> #lightgreen class DC_DetectorSensorSBIG #lightgreen @@ -134,7 +134,7 @@ class DC_DetectorShutterSBIG #lightgreen class DC_FilterSelectorSBIG #lightgreen class DS_SBIG #lightgreen -AD_SBIG -d-> DC_SBIG :use +AgentDeviceSBIG -d-> DC_SBIG :use /'DC_SBIG o- DS_SBIG'/ /' Controllers '/ diff --git a/src/device_controller/abstract_component/base.py b/src/device_controller/abstract_component/base.py deleted file mode 100755 index 599c26f..0000000 --- a/src/device_controller/abstract_component/base.py +++ /dev/null @@ -1,725 +0,0 @@ -#!/usr/bin/env python3 - -"""Socket Client Telescope (abstract) implementation - -To be used as a base class (interface) for any concrete socket client telescope class -""" - - -# Standard library imports -#from enum import Enum -import functools -import logging -import socket -import sys -import threading -import time - -# Third party imports - - -# Local application imports - -#sys.path.append("../../..") -sys.path.append("../../../..") -#import src.core.pyros_django.utils.celme as celme -import src.core.celme as celme - -#sys.path.append('../..') -#from src.client.socket_client_abstract import UnknownCommandException, SocketClientAbstract -##from src_socket.client.socket_client_abstract import * -##from src_device.client.client_channel import * -sys.path.append("../..") -from device_controller.logs import * -from device_controller.channels.client_channel_socket import ClientChannelSocket -from device_controller.channels.client_channel_serial import ClientChannelSerial -from device_controller.channels.client_channel_usb import ClientChannelUSB - - - - -# Execute also "set" and "do" commands -GET_ONLY=False -# Execute only "get" commands -#GET_ONLY=True - -# Default timeouts -TIMEOUT_SEND = 10 -TIMEOUT_RECEIVE = 10 - - -''' -class c(Enum): - - # GET, SET - DEC = 'DEC' - RA = 'RA' - RA_DEC = 'RA_DEC' - - # DO - PARK = 'PARK' - WARM_START = 'WARM_START' -''' - -# DECORATOR -def generic_cmd(func): - #def wrapper_generic_cmd(*args, **kwargs): - @functools.wraps(func) - def wrapper_generic_cmd(self, values_to_set=None): - #print("func name is", func.__name__) - return self.execute_generic_cmd(func.__name__, values_to_set) - return wrapper_generic_cmd - - -class DeviceCommand: - - full_name:str = '' - name = None - args = None - # Device component type - devtype = None - - def __init__(self, cmd_full_name:str, dev_comp_type:str=None, cmd_args:str=None): - self.full_name = cmd_full_name - self.name = cmd_full_name - self.devtype = dev_comp_type - self.args = cmd_args - if self.is_generic(): - dev_comp_type,cmd_name,cmd_args = self.get_full_name_parts() - self.name = cmd_name - if dev_comp_type: self.devtype = dev_comp_type - if cmd_args: self.args = cmd_args - - def __str__(self): - return (f"Commmand '{self.full_name}'") - - def is_generic(self): - ''' - cmd_name = self.full_name - if '.' in self.full_name: - cmd_name = self.full_name.split('.')[1] - ''' - cmd_name = self.full_name[self.full_name.find('.')+1:] - return cmd_name.startswith('do_') or cmd_name.startswith('get_') or cmd_name.startswith('set_') - - ''' - @classmethod - def is_generic_cmd_name(cls, cmd_name:str): - if '.' in cmd_name: - cmd_name = cmd_name.split('.')[1] - return cmd_name.startswith('do_') or cmd_name.startswith('get_') or cmd_name.startswith('set_') - - def is_generic(self): - #return type(self).is_generic_cmd_name(self.full_name) - return self.is_generic_cmd_name(self.full_name) - #return DeviceCommand.is_generic_cmd_name(self.full_name) - #return self.name.startswith('do_') or self.name.startswith('get_') or self.name.startswith('set_') - ''' - - @property - def name_and_args(self): - cmd_name_and_args = self.full_name - if '.' in cmd_name_and_args: - cmd_name_and_args = cmd_name_and_args.split('.')[1] - return cmd_name_and_args - - def get_full_name_parts(self): - cmd_name = self.full_name - devtype = None - cmd_args = None - if '.' in cmd_name: - devtype, cmd_name = cmd_name.split('.') - if ' ' in cmd_name: - cmd_name, *cmd_args = cmd_name.split(' ') - return devtype, cmd_name, cmd_args - - - - - - -class GenericResult: - ''' Usage: - res = execute(command) - print("result is", res) - if res.ko: raise UnexpectedReturnCode() - if res.ok: - ... - ''' - # By default, bad result - ok = True - ko = False - - def __init__(self, native_result:str, ok=True): - self.txt = native_result - self.ok = ok - self.ko = not ok - def __str__(self): - return self.txt - ''' - def __repr__(self): - return self.txt - def __get__(self, instance, owner): - return self.b - def __set__(self, instance, value): - self.b = value - ''' - - - -class UnexpectedCommandReturnCode(Exception): - pass -class TimeoutException(Exception): - pass -class UnknownCommandException(Exception): - pass - ''' - def __init__(self,*args,**kwargs): - super().__init__(self,*args,**kwargs) - ''' - - - -#TODO: remove ClientChannelAbstract, and set instead a ClientChannel -#class DeviceControllerAbstract(SocketClientAbstract): -##class DeviceControllerAbstract(ClientChannel): -class DeviceControllerAbstract(): - - _device_simulator = None - _thread_device_simulator = None - - _device_host = "localhost" - _device_port = None - - # List of device controller (dc) components (by default, None) - _my_dc_components = [] - - # ClientChannel used by the device controller (to be set during __init__ via set_client_channel()) - my_channel = None - - # @abstract (to be overriden) - _cmd_device_concrete = {} - _cmd_device_abstract = {} - _cmd = { - # GET-SET commands: - - 'get_timezone': [], - 'set_timezone': [], - - 'get_date': [], - 'set_date': [], - - 'get_time': [], - 'set_time': [], - - # DO commands: - 'do_init': ['do_init'], - 'do_park': [], - } - - - ##def __init__(self, device_host:str="localhost", device_port:int=11110, PROTOCOL:str="TCP", buffer_size=1024, DEBUG=False): - def __init__(self, device_host:str="localhost", device_port:int=11110, PROTOCOL="TCP", buffer_size=1024, DEBUG=False, device_sim=None): - ''' - :param device_host: server IP or hostname - :param device_port: server port - :param PROTOCOL: "SOCKET-TCP", "SOCKET-UDP", "SERIAL", or "USB" - ''' - print("IN DeviceControllerAbstract") - self._device_host = device_host - self._device_port = device_port - - ##super().__init__(device_host, device_port, PROTOCOL, buffer_size, DEBUG) - set_logger(DEBUG) - log_d("Logger configured") - - if isinstance(PROTOCOL, str): - - # If LOCALHOST, launch the device SIMULATOR - if device_host=="localhost": - self._device_simulator = device_sim - print("SIMU IS", device_sim, self._device_simulator) - self._thread_device_simulator = threading.Thread(target=self.device_simulator_run) - self._thread_device_simulator.start() - - if PROTOCOL.startswith("SOCKET"): self.my_channel:ClientChannel = ClientChannelSocket(device_host, device_port, PROTOCOL, buffer_size, DEBUG) - elif PROTOCOL == "SERIAL": self.my_channel:ClientChannel = ClientChannelSerial(device_host, device_port, buffer_size, DEBUG) - elif PROTOCOL == "USB": self.my_channel:ClientChannel = ClientChannelUSB(device_host, device_port, buffer_size, DEBUG) - else: raise Exception("Unknown Channel", PROTOCOL) - - else: - - self.my_channel = PROTOCOL - - # overwrite abstract _cmd dictionary with subclass native _cmd_native dictionary: - #self._cmd = {**self._cmd, **self._cmd_native} - self._cmd = {**self._cmd, **self._cmd_device_abstract, **self._cmd_device_concrete} - print("MY COMMANDS ARE:", self._cmd) - - - # So that we can use this with the "with" statement (context manager) - def __enter__(self): - return self - def __exit__(self, type, value, traceback): - self.my_channel.__exit__(type, value, traceback) - - ''' - def set_logger(self, DEBUG): - self.my_channel.set_logger(DEBUG) - ''' - - def device_simulator_run(self): - #HOST, PORT = "localhost", 11110 - #with get_SocketServer_UDP_TCP(HOST, PORT, "UDP") as myserver: - print("Starting device simulator on (host:port): ", self._device_host+':'+str(self._device_port)) - self._device_simulator.serve_forever(self._device_port) - #with get_SocketServer_UDP_TCP(self.HOST, self.PORT, "UDP") as myserver: myserver.serve_forever() - ''' - myserver = get_SocketServer_UDP_TCP(self.HOST, self.PORT, "UDP") - myserver.serve_forever() - ''' - - - def _connect_to_device(self): - self.my_channel._connect_to_server() - - def get_celme_longitude(self, longitude): - return celme.Angle(longitude).sexagesimal("d:+0180.0") - def get_celme_latitude(self, latitude): - return celme.Angle(latitude).sexagesimal("d:+090.0") - - #@override ClientChannel send_data - def send_data(self, data:str): - data_encapsulated = self.format_data_to_send(data) - self.my_channel.send_data(data_encapsulated) - ''' - The chosen way to send data is this: - # - :GD# - b'00030000:GD#\x00' - - Another way to send data (which also works), is it better ? - # - :GD# - ###tsock.mysock.sendto(b'\x00\x00\x00\x01\x00\x00\x00\x00\x3A\x47\x44\x23\x00', (HOST, PORT)) - # - :GR# - ###tsock.mysock.sendto(b'\x00\x00\x00\x01\x00\x00\x00\x00\x3A\x47\x52\x23\x00', (HOST, PORT)) - # - ACK 06 OK !!! : - tsock.mysock.sendto(b'\x00\x00\x00\x01\x00\x00\x00\x00\x00\x06\x00\x00', (HOST, PORT)) - - Which one is the best method ? - ''' - #log_d("NATIVE Command to send is "+repr(data)) - ##encapsulated_data = self.encapsulate_data_to_send(data) - #print("before _send", encapsulated_data) - #print("before _send", repr(encapsulated_data)) - ##self._send_data(encapsulated_data) - ##self.my_channel.send_data(encapsulated_data) - #log_i(f'Sent: {encapsulated_data}') - ''' - def _send_data(self, data): - self.my_channel._send_data(data) - ''' - - #@override ClientChannel receive_data - def receive_data(self)->str: - ##data_received_bytes = self._receive_data() - data_received = self.my_channel.receive_data() - #log_d("Received (all data): {}".format(data_received)) - #log_d("data in bytes: "+str(bytes(data_received, "utf-8"))) - data = self.unformat_received_data(data_received) - log_i("RECEIVED (useful data): {}".format(data)) - return data - ''' - def _receive_data(self): - return self.my_channel._receive_data() - ''' - - # Encapsulate useful data to be ready for sending - # By default, do nothing - #@abstract - def format_data_to_send(self, data:str): - return self.encapsulate_data_to_send(data) - #@deprecated - def encapsulate_data_to_send(self, data:str): - return data - - # Extract useful data from received raw data - # By default, do nothing - #@abstract - def unformat_received_data(self, data:str): - return self.uncap_received_data(data) - #@deprecated - def uncap_received_data(self, data:str): - #return data_received.decode() - return data - - ''' - def encapsulate_data_to_send(self, command:str): - return self.my_channel.encapsulate_data_to_send(command) - def uncap_received_data(self, data_received:str): - return self.my_channel.uncap_received_data(data_received) - ''' - - - def get_utc_date(self): - return celme.Date("now").iso(0) - #return celme.Date("now").ymdhms() - - - def close(self): - self.my_channel.close() - # Stop device simulator (only if used) - if self._device_host=="localhost": - print("Stopping device simulator") - self._device_simulator.stop() - - - ''' - def is_generic_cmd(self, raw_input_cmd:str) -> bool: - print("raw_input_cmd is", raw_input_cmd) - # Using Google documentation format (https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html#example-google) - #"" Is this a generic command ? - - Args: - raw_input_cmd: a command in string format (like 'set_state active' or 'get_ra' or 'set_ra 20:00:00' or 'set_radec 20:00:00 90:00:00" or 'do_park'...) - - Returns: - either False or (cmd, [args]) with cmd like "get_ra" and [args] like ['20:00:00', '90:00:00'] - - #"" - #return cmd.startswith('get_') or cmd.startswith('set_') or cmd.startswith('do_') - #cmds = ['get ', 'get_', 'set ', 'set_', 'do ', 'do_'] - #'' - seps = (" ", "_") - #cmds = list(x+y for x in cmd for y in sep) - for cmd in cmds: - for sep in seps: - generic_cmd = cmd+sep - if raw_input_cmd.startswith(generic_cmd): - # Is there value(s) passed ? - if len(raw_input_cmd) > len(generic_cmd): - values = raw_input_cmd[len(generic_cmd):] - values = values.split(' ') - # return cmd like "get_ra", [and values] - return generic_cmd.replace(' ','_'), values - return False, False - #'' - ##cmds = ("get","set","do") - - #'' - # ex: "set radec" => "set_radec" - raw_input_cmd = raw_input_cmd.strip() - cmd_splitted = raw_input_cmd.split(' ') - if len(cmd_splitted) == 1: return False,False - generic_cmd = cmd_splitted[0] + '_' + cmd_splitted[1] - #'' - # Ex: "set_radec 15 30", "do_init", "get_radec", "set_state active", "do_goto_radec 15 45"... - tokens = raw_input_cmd.split(' ') - generic_cmd = tokens[0] - - # Check this generic command exists - #if (generic_cmd not in self._cmd.keys()): return False,False - if generic_cmd not in self._cmd: return False,False - # Is there value(s) passed ? - ###if len(cmd_splitted) > 2: values_to_set = cmd_splitted[2:] - args = tokens[1:] if len(tokens)>1 else None - # ex: return "set_radec", ["20:00:00", "90:00:00"] - return generic_cmd, args - ''' - - - #res = self.getDeviceControllerForType(cmd.device_type).execute_cmd(cmd.full_name) - def get_dc_component_for_type(self, dc_component_type:str): #->DeviceControllerAbstract: - # By default, return myself (as a DeviceController component) - # ex1: None - # ex2: "Telescope" (is in "AgentDeviceTelescopeGemini") - #if dc_component_type is None or dc_component_type in self.__class__.__name__ : return self - if dc_component_type is None or dc_component_type in type(self).__name__ : return self - #for dcc in type(self).mro(): - #for dcc in type(self).__bases__ : - for dcc in self._my_dc_components: - print(dc_component_type, "in ??????", type(dcc).__name__) - #if dc_component_type in dcct.__class__.__name__: - if dc_component_type in type(dcc).__name__: - return dcc - raise Exception("NO DEVICE CONTROLLER COMPONENT FOUND FOR THIS TYPE: "+dc_component_type) - - - #def execute_cmd(self, cmd:DeviceCommand)->GenericResult: - def execute_cmd(self, raw_input_cmd:str)->GenericResult: - ''' - :param raw_input_cmd: - ''' - - #generic_cmd, args = self.is_generic_cmd(raw_input_cmd) - cmd = DeviceCommand(raw_input_cmd) - print("cmd is", cmd, raw_input_cmd) - - # GENERIC command - #if generic_cmd is not False: - if cmd.is_generic(): - print("GENERIC COMMAND") - #return self.execute_generic_cmd(generic_cmd, args) - return self.execute_generic_cmd(cmd.name, cmd.args, cmd.devtype) - - # NATIVE command - ''' - if cmd.startswith('get_'): - #generic_cmd,_ = request[4:].split('(') - generic_cmd = cmd[4:] - if (generic_cmd not in self._cmd_getset.keys()) and (generic_cmd not in self._cmd_do.keys()): - #eval(request) - return self.get_radec() - print("cmd is", generic_cmd) - return self._get(generic_cmd) - return - ''' - # NATIVE command - print("NATIVE COMMAND") - #res_native = self.execute_native_cmd(raw_input_cmd) - res_native = self.execute_native_cmd(cmd.name_and_args) - return GenericResult(res_native) - - - #def execute_native_cmd(self, request:str, awaited_res_if_ok=None)->GenericResult: - def execute_native_cmd(self, native_cmd:str) -> str: - """ Execute a native command - - Args: - native_cmd: a native command - - Returns: - the command result - - """ - print("NATIVE Command to send is "+ repr(native_cmd)) - #self.send_request(native_cmd) - self.send_native_cmd(native_cmd) - native_res = self.receive_data() - return native_res - ''' - ok = True if not awaited_res_if_ok else (native_res == awaited_res_if_ok) - return GenericResult(native_res, ok) - ''' - - - ''' - def execute_native_cmd_OLD(self, request:str)->str: - self.send_request(request) - native_res = self.receive_data() - return native_res - ''' - - - def execute_unformated_native_cmd(self, request:str) -> str: - request = self.formated_cmd(request) - #return self.execute_native_cmd_OLD(request) - return self.execute_native_cmd(request) - - - def send_native_cmd(self, native_cmd:str)->str: - return self.send_data(native_cmd) - - - #@deprecated - def send_request(self, request:str)->str: - return self.send_native_cmd(request) - - - def print_available_commands(self): - print("\nAvailable commands are:") - print("- GET commands:") - #print (list(cmd.replace('_',' ') for cmd in self._cmd.keys() if cmd.startswith('get_'))) - print (list(cmd for cmd in self._cmd.keys() if cmd.startswith('get_'))) - print("- SET commands:") - print (list(cmd for cmd in self._cmd.keys() if cmd.startswith('set_'))) - print("- DO commands:") - print (list(cmd for cmd in self._cmd.keys() if cmd.startswith('do_'))) - - - def available_commands(self): - return list(self._cmd.keys()) - - - # @abstract - def formated_cmd(self, cmd:str, value:str=None)->str: - return cmd - - - #def run_func(self, func, arg=None): - def run_func(self, func, *args): - #print("args", args) - if args: - return getattr(self, func)(*args) - else: - return getattr(self, func)() - - ''' - TELESCOPE COMMANDS (abstract methods) - ''' - - #def execute_generic_cmd(self, generic_cmd:DeviceCommand)->str: - def execute_generic_cmd(self, generic_cmd:str, values_to_set:str=None, dc_component_type:str=None)->str: - ''' Execute a generic command - - :param generic_cmd: str like "get_ra" or "set_ra" or "do_park"... - :param value: only for a "set_" cmd - ''' - print("execute_generic_cmd() from", self) - # If generic_cmd is for a specific device component (dc), pass it to this dc (instead of me) - print("dc_component_type is: ", dc_component_type) - ####if dc_component_type and dc_component_type not in self.__class__.__name__ : - if dc_component_type: - dcc = self.get_dc_component_for_type(dc_component_type) - print("*** EXECUTÉ PAR COMPONENT", dcc) - #return (DCC)(self.execute_generic_cmd(generic_cmd, values_to_set, None)) - return dcc.execute_generic_cmd(generic_cmd, values_to_set, None) - - #log_d("\n\nGENERIC Command to send is "+generic_cmd) - print("\n\nGENERIC Command to send is ", generic_cmd) - print("My ("+type(self).__name__+") commands are:", self._cmd) - - if generic_cmd not in self._cmd: raise NotImplementedError - native_cmd_infos = self._cmd[generic_cmd] - # If this generic command has no corresponding native command, raise NotImplementedError - #if generic_cmd not in self._cmd.keys(): raise UnknownCommandException() - if not native_cmd_infos: raise NotImplementedError - # Get corresponding native command: - native_cmd = native_cmd_infos[0] - if not native_cmd: raise NotImplementedError - - # MACRO-COMMAND (ex: native_cmd == "do_goto", "do_init", "get_radec") - if native_cmd == generic_cmd: - print("MACRO-COMMAND") - #print("cmd,val", native_cmd, values_to_set) - #res:GenericResult = self.run_func(native_cmd, *values_to_set) - if values_to_set: - print("with args") - res = self.run_func(native_cmd, *values_to_set) - #res = getattr(self, native_cmd)(values_to_set) - else: - res = self.run_func(native_cmd) - #res = getattr(self, native_cmd)() - #if res is None: res = 'ok' - # res should be a GenericResult - if not isinstance(res, GenericResult): raise Exception("Should be a GenericResult", res) - return res - - # NATIVE COMMAND (ex: native_cmd == "GR") - native_cmd = self.formated_cmd(native_cmd, values_to_set) - awaited_res_if_ok = None - if len(native_cmd_infos) > 1: awaited_res_if_ok = native_cmd_infos[1] - #native_res = self.execute_native_cmd(self.formated_cmd(native_cmd,value), awaited_res_ok) - native_res = self.execute_native_cmd(native_cmd) - ok = True if not awaited_res_if_ok else (native_res == awaited_res_if_ok) - return GenericResult(native_res, ok) - - - - ''' - **************************** - **************************** - GENERIC TELESCOPE COMMANDS (abstract methods) - **************************** - **************************** - ''' - - - - ''' - **************************** - GENERIC GET & SET commands - **************************** - ''' - - - @generic_cmd - def get_timezone(self): pass - #def get_timezone(self): return self.execute_generic_cmd('get_timezone') - @generic_cmd - def set_timezone(self, hh): pass - #def set_timezone(self, hh): return self.execute_generic_cmd('set_timezone', hh) - - @generic_cmd - def get_date(self): pass - @generic_cmd - def set_date(self, mmddyy): pass - - @generic_cmd - def get_time(self): pass - @generic_cmd - def set_time(self, hhmmss): pass - - - - ''' - **************************** - GENERIC DO commands - **************************** - ''' - - # @abstract - #def do_INIT(self): return self._do("INIT") - - ''' do_PARK() (p103) - - STARTUP position = CWD - - :hC# - - position required for a Cold or Warm Start, pointing to the celestial pole of the given hemisphere (north or south), - with the counterweight pointing downwards (CWD position). From L4, V1.0 up - - HOME position parking => par defaut, c'est CWD, mais ca peut etre different - - :hP# - - defaults to the celestial pole visible at the given hemisphere (north or south) and can be set by the user - ''' - # @abstract - def do_PARK(self): pass - #def do_PARK(self): return self._do("PARK") - - # @abstract - def do_start(self): pass - def do_stop(self): pass - - # @abstract MACRO - def do_init(self): raise NotImplementedError - - - - - -# TODO: empecher de creer une instance de cette classe abstraite -# Avec ABC ? - -''' -if __name__ == "__main__": - - #HOST, PORT = "localhost", 9999 - #HOST, PORT = "localhost", 20001 - HOST, PORT = "localhost", 11110 - - # Classic usage: - #tsock = SocketClient_UDP_TCP(HOST, PORT, "UDP") - # More elegant usage, using "with": - with SocketClient_ABSTRACT(HOST, PORT, "UDP") as tsock: - - # 0) CONNECT to server (only for TCP, does nothing for UDP) - tsock._connect_to_server() - - while True: - - # 1) SEND REQUEST data to server - # saisie de la requête au clavier et suppression des espaces des 2 côtés - data = input("REQUEST TO SERVER [ex: ':GD#' (Get Dec), ':GR#' (Get RA)']: ").strip() - # test d'arrêt - if data=="": break - #data_to_send = bytes(data + "\n", "utf-8") - tsock.send_data(data) - #mysock.sendto("%s" % data, (HOST, PORT)) - #print("Sent: {}".format(data)) - - # 2) RECEIVE REPLY data from server - data_received = tsock.receive_data() - #reponse, adr = mysock.recvfrom(buf) - #print("Received: {}".format(data_received)) - #print("Useful data received: {}".format(data_useful)) - print('\n') - - #tsock.close() -''' \ No newline at end of file diff --git a/src/device_controller/abstract_component/detector_sensor.py b/src/device_controller/abstract_component/detector_sensor.py index bcab3eb..caa5b45 100755 --- a/src/device_controller/abstract_component/detector_sensor.py +++ b/src/device_controller/abstract_component/detector_sensor.py @@ -22,7 +22,7 @@ import src.core.celme as celme #from device_controller.abstract_component.base import * sys.path.append("../..") #from device_controller.abstract_component.base import * -from device_controller.abstract_component.base import DeviceControllerAbstract +from device_controller.abstract_component.device_controller import DeviceControllerAbstract # Default timeouts diff --git a/src/device_controller/abstract_component/detector_shutter.py b/src/device_controller/abstract_component/detector_shutter.py index b80abde..89a5232 100755 --- a/src/device_controller/abstract_component/detector_shutter.py +++ b/src/device_controller/abstract_component/detector_shutter.py @@ -22,7 +22,7 @@ import src.core.celme as celme #from device_controller.abstract_component.base import * sys.path.append("../..") #from device_controller.abstract_component.base import * -from device_controller.abstract_component.base import DeviceControllerAbstract +from device_controller.abstract_component.device_controller import DeviceControllerAbstract diff --git a/src/device_controller/abstract_component/device_controller.py b/src/device_controller/abstract_component/device_controller.py new file mode 100755 index 0000000..599c26f --- /dev/null +++ b/src/device_controller/abstract_component/device_controller.py @@ -0,0 +1,725 @@ +#!/usr/bin/env python3 + +"""Socket Client Telescope (abstract) implementation + +To be used as a base class (interface) for any concrete socket client telescope class +""" + + +# Standard library imports +#from enum import Enum +import functools +import logging +import socket +import sys +import threading +import time + +# Third party imports + + +# Local application imports + +#sys.path.append("../../..") +sys.path.append("../../../..") +#import src.core.pyros_django.utils.celme as celme +import src.core.celme as celme + +#sys.path.append('../..') +#from src.client.socket_client_abstract import UnknownCommandException, SocketClientAbstract +##from src_socket.client.socket_client_abstract import * +##from src_device.client.client_channel import * +sys.path.append("../..") +from device_controller.logs import * +from device_controller.channels.client_channel_socket import ClientChannelSocket +from device_controller.channels.client_channel_serial import ClientChannelSerial +from device_controller.channels.client_channel_usb import ClientChannelUSB + + + + +# Execute also "set" and "do" commands +GET_ONLY=False +# Execute only "get" commands +#GET_ONLY=True + +# Default timeouts +TIMEOUT_SEND = 10 +TIMEOUT_RECEIVE = 10 + + +''' +class c(Enum): + + # GET, SET + DEC = 'DEC' + RA = 'RA' + RA_DEC = 'RA_DEC' + + # DO + PARK = 'PARK' + WARM_START = 'WARM_START' +''' + +# DECORATOR +def generic_cmd(func): + #def wrapper_generic_cmd(*args, **kwargs): + @functools.wraps(func) + def wrapper_generic_cmd(self, values_to_set=None): + #print("func name is", func.__name__) + return self.execute_generic_cmd(func.__name__, values_to_set) + return wrapper_generic_cmd + + +class DeviceCommand: + + full_name:str = '' + name = None + args = None + # Device component type + devtype = None + + def __init__(self, cmd_full_name:str, dev_comp_type:str=None, cmd_args:str=None): + self.full_name = cmd_full_name + self.name = cmd_full_name + self.devtype = dev_comp_type + self.args = cmd_args + if self.is_generic(): + dev_comp_type,cmd_name,cmd_args = self.get_full_name_parts() + self.name = cmd_name + if dev_comp_type: self.devtype = dev_comp_type + if cmd_args: self.args = cmd_args + + def __str__(self): + return (f"Commmand '{self.full_name}'") + + def is_generic(self): + ''' + cmd_name = self.full_name + if '.' in self.full_name: + cmd_name = self.full_name.split('.')[1] + ''' + cmd_name = self.full_name[self.full_name.find('.')+1:] + return cmd_name.startswith('do_') or cmd_name.startswith('get_') or cmd_name.startswith('set_') + + ''' + @classmethod + def is_generic_cmd_name(cls, cmd_name:str): + if '.' in cmd_name: + cmd_name = cmd_name.split('.')[1] + return cmd_name.startswith('do_') or cmd_name.startswith('get_') or cmd_name.startswith('set_') + + def is_generic(self): + #return type(self).is_generic_cmd_name(self.full_name) + return self.is_generic_cmd_name(self.full_name) + #return DeviceCommand.is_generic_cmd_name(self.full_name) + #return self.name.startswith('do_') or self.name.startswith('get_') or self.name.startswith('set_') + ''' + + @property + def name_and_args(self): + cmd_name_and_args = self.full_name + if '.' in cmd_name_and_args: + cmd_name_and_args = cmd_name_and_args.split('.')[1] + return cmd_name_and_args + + def get_full_name_parts(self): + cmd_name = self.full_name + devtype = None + cmd_args = None + if '.' in cmd_name: + devtype, cmd_name = cmd_name.split('.') + if ' ' in cmd_name: + cmd_name, *cmd_args = cmd_name.split(' ') + return devtype, cmd_name, cmd_args + + + + + + +class GenericResult: + ''' Usage: + res = execute(command) + print("result is", res) + if res.ko: raise UnexpectedReturnCode() + if res.ok: + ... + ''' + # By default, bad result + ok = True + ko = False + + def __init__(self, native_result:str, ok=True): + self.txt = native_result + self.ok = ok + self.ko = not ok + def __str__(self): + return self.txt + ''' + def __repr__(self): + return self.txt + def __get__(self, instance, owner): + return self.b + def __set__(self, instance, value): + self.b = value + ''' + + + +class UnexpectedCommandReturnCode(Exception): + pass +class TimeoutException(Exception): + pass +class UnknownCommandException(Exception): + pass + ''' + def __init__(self,*args,**kwargs): + super().__init__(self,*args,**kwargs) + ''' + + + +#TODO: remove ClientChannelAbstract, and set instead a ClientChannel +#class DeviceControllerAbstract(SocketClientAbstract): +##class DeviceControllerAbstract(ClientChannel): +class DeviceControllerAbstract(): + + _device_simulator = None + _thread_device_simulator = None + + _device_host = "localhost" + _device_port = None + + # List of device controller (dc) components (by default, None) + _my_dc_components = [] + + # ClientChannel used by the device controller (to be set during __init__ via set_client_channel()) + my_channel = None + + # @abstract (to be overriden) + _cmd_device_concrete = {} + _cmd_device_abstract = {} + _cmd = { + # GET-SET commands: + + 'get_timezone': [], + 'set_timezone': [], + + 'get_date': [], + 'set_date': [], + + 'get_time': [], + 'set_time': [], + + # DO commands: + 'do_init': ['do_init'], + 'do_park': [], + } + + + ##def __init__(self, device_host:str="localhost", device_port:int=11110, PROTOCOL:str="TCP", buffer_size=1024, DEBUG=False): + def __init__(self, device_host:str="localhost", device_port:int=11110, PROTOCOL="TCP", buffer_size=1024, DEBUG=False, device_sim=None): + ''' + :param device_host: server IP or hostname + :param device_port: server port + :param PROTOCOL: "SOCKET-TCP", "SOCKET-UDP", "SERIAL", or "USB" + ''' + print("IN DeviceControllerAbstract") + self._device_host = device_host + self._device_port = device_port + + ##super().__init__(device_host, device_port, PROTOCOL, buffer_size, DEBUG) + set_logger(DEBUG) + log_d("Logger configured") + + if isinstance(PROTOCOL, str): + + # If LOCALHOST, launch the device SIMULATOR + if device_host=="localhost": + self._device_simulator = device_sim + print("SIMU IS", device_sim, self._device_simulator) + self._thread_device_simulator = threading.Thread(target=self.device_simulator_run) + self._thread_device_simulator.start() + + if PROTOCOL.startswith("SOCKET"): self.my_channel:ClientChannel = ClientChannelSocket(device_host, device_port, PROTOCOL, buffer_size, DEBUG) + elif PROTOCOL == "SERIAL": self.my_channel:ClientChannel = ClientChannelSerial(device_host, device_port, buffer_size, DEBUG) + elif PROTOCOL == "USB": self.my_channel:ClientChannel = ClientChannelUSB(device_host, device_port, buffer_size, DEBUG) + else: raise Exception("Unknown Channel", PROTOCOL) + + else: + + self.my_channel = PROTOCOL + + # overwrite abstract _cmd dictionary with subclass native _cmd_native dictionary: + #self._cmd = {**self._cmd, **self._cmd_native} + self._cmd = {**self._cmd, **self._cmd_device_abstract, **self._cmd_device_concrete} + print("MY COMMANDS ARE:", self._cmd) + + + # So that we can use this with the "with" statement (context manager) + def __enter__(self): + return self + def __exit__(self, type, value, traceback): + self.my_channel.__exit__(type, value, traceback) + + ''' + def set_logger(self, DEBUG): + self.my_channel.set_logger(DEBUG) + ''' + + def device_simulator_run(self): + #HOST, PORT = "localhost", 11110 + #with get_SocketServer_UDP_TCP(HOST, PORT, "UDP") as myserver: + print("Starting device simulator on (host:port): ", self._device_host+':'+str(self._device_port)) + self._device_simulator.serve_forever(self._device_port) + #with get_SocketServer_UDP_TCP(self.HOST, self.PORT, "UDP") as myserver: myserver.serve_forever() + ''' + myserver = get_SocketServer_UDP_TCP(self.HOST, self.PORT, "UDP") + myserver.serve_forever() + ''' + + + def _connect_to_device(self): + self.my_channel._connect_to_server() + + def get_celme_longitude(self, longitude): + return celme.Angle(longitude).sexagesimal("d:+0180.0") + def get_celme_latitude(self, latitude): + return celme.Angle(latitude).sexagesimal("d:+090.0") + + #@override ClientChannel send_data + def send_data(self, data:str): + data_encapsulated = self.format_data_to_send(data) + self.my_channel.send_data(data_encapsulated) + ''' + The chosen way to send data is this: + # - :GD# + b'00030000:GD#\x00' + + Another way to send data (which also works), is it better ? + # - :GD# + ###tsock.mysock.sendto(b'\x00\x00\x00\x01\x00\x00\x00\x00\x3A\x47\x44\x23\x00', (HOST, PORT)) + # - :GR# + ###tsock.mysock.sendto(b'\x00\x00\x00\x01\x00\x00\x00\x00\x3A\x47\x52\x23\x00', (HOST, PORT)) + # - ACK 06 OK !!! : + tsock.mysock.sendto(b'\x00\x00\x00\x01\x00\x00\x00\x00\x00\x06\x00\x00', (HOST, PORT)) + + Which one is the best method ? + ''' + #log_d("NATIVE Command to send is "+repr(data)) + ##encapsulated_data = self.encapsulate_data_to_send(data) + #print("before _send", encapsulated_data) + #print("before _send", repr(encapsulated_data)) + ##self._send_data(encapsulated_data) + ##self.my_channel.send_data(encapsulated_data) + #log_i(f'Sent: {encapsulated_data}') + ''' + def _send_data(self, data): + self.my_channel._send_data(data) + ''' + + #@override ClientChannel receive_data + def receive_data(self)->str: + ##data_received_bytes = self._receive_data() + data_received = self.my_channel.receive_data() + #log_d("Received (all data): {}".format(data_received)) + #log_d("data in bytes: "+str(bytes(data_received, "utf-8"))) + data = self.unformat_received_data(data_received) + log_i("RECEIVED (useful data): {}".format(data)) + return data + ''' + def _receive_data(self): + return self.my_channel._receive_data() + ''' + + # Encapsulate useful data to be ready for sending + # By default, do nothing + #@abstract + def format_data_to_send(self, data:str): + return self.encapsulate_data_to_send(data) + #@deprecated + def encapsulate_data_to_send(self, data:str): + return data + + # Extract useful data from received raw data + # By default, do nothing + #@abstract + def unformat_received_data(self, data:str): + return self.uncap_received_data(data) + #@deprecated + def uncap_received_data(self, data:str): + #return data_received.decode() + return data + + ''' + def encapsulate_data_to_send(self, command:str): + return self.my_channel.encapsulate_data_to_send(command) + def uncap_received_data(self, data_received:str): + return self.my_channel.uncap_received_data(data_received) + ''' + + + def get_utc_date(self): + return celme.Date("now").iso(0) + #return celme.Date("now").ymdhms() + + + def close(self): + self.my_channel.close() + # Stop device simulator (only if used) + if self._device_host=="localhost": + print("Stopping device simulator") + self._device_simulator.stop() + + + ''' + def is_generic_cmd(self, raw_input_cmd:str) -> bool: + print("raw_input_cmd is", raw_input_cmd) + # Using Google documentation format (https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html#example-google) + #"" Is this a generic command ? + + Args: + raw_input_cmd: a command in string format (like 'set_state active' or 'get_ra' or 'set_ra 20:00:00' or 'set_radec 20:00:00 90:00:00" or 'do_park'...) + + Returns: + either False or (cmd, [args]) with cmd like "get_ra" and [args] like ['20:00:00', '90:00:00'] + + #"" + #return cmd.startswith('get_') or cmd.startswith('set_') or cmd.startswith('do_') + #cmds = ['get ', 'get_', 'set ', 'set_', 'do ', 'do_'] + #'' + seps = (" ", "_") + #cmds = list(x+y for x in cmd for y in sep) + for cmd in cmds: + for sep in seps: + generic_cmd = cmd+sep + if raw_input_cmd.startswith(generic_cmd): + # Is there value(s) passed ? + if len(raw_input_cmd) > len(generic_cmd): + values = raw_input_cmd[len(generic_cmd):] + values = values.split(' ') + # return cmd like "get_ra", [and values] + return generic_cmd.replace(' ','_'), values + return False, False + #'' + ##cmds = ("get","set","do") + + #'' + # ex: "set radec" => "set_radec" + raw_input_cmd = raw_input_cmd.strip() + cmd_splitted = raw_input_cmd.split(' ') + if len(cmd_splitted) == 1: return False,False + generic_cmd = cmd_splitted[0] + '_' + cmd_splitted[1] + #'' + # Ex: "set_radec 15 30", "do_init", "get_radec", "set_state active", "do_goto_radec 15 45"... + tokens = raw_input_cmd.split(' ') + generic_cmd = tokens[0] + + # Check this generic command exists + #if (generic_cmd not in self._cmd.keys()): return False,False + if generic_cmd not in self._cmd: return False,False + # Is there value(s) passed ? + ###if len(cmd_splitted) > 2: values_to_set = cmd_splitted[2:] + args = tokens[1:] if len(tokens)>1 else None + # ex: return "set_radec", ["20:00:00", "90:00:00"] + return generic_cmd, args + ''' + + + #res = self.getDeviceControllerForType(cmd.device_type).execute_cmd(cmd.full_name) + def get_dc_component_for_type(self, dc_component_type:str): #->DeviceControllerAbstract: + # By default, return myself (as a DeviceController component) + # ex1: None + # ex2: "Telescope" (is in "AgentDeviceTelescopeGemini") + #if dc_component_type is None or dc_component_type in self.__class__.__name__ : return self + if dc_component_type is None or dc_component_type in type(self).__name__ : return self + #for dcc in type(self).mro(): + #for dcc in type(self).__bases__ : + for dcc in self._my_dc_components: + print(dc_component_type, "in ??????", type(dcc).__name__) + #if dc_component_type in dcct.__class__.__name__: + if dc_component_type in type(dcc).__name__: + return dcc + raise Exception("NO DEVICE CONTROLLER COMPONENT FOUND FOR THIS TYPE: "+dc_component_type) + + + #def execute_cmd(self, cmd:DeviceCommand)->GenericResult: + def execute_cmd(self, raw_input_cmd:str)->GenericResult: + ''' + :param raw_input_cmd: + ''' + + #generic_cmd, args = self.is_generic_cmd(raw_input_cmd) + cmd = DeviceCommand(raw_input_cmd) + print("cmd is", cmd, raw_input_cmd) + + # GENERIC command + #if generic_cmd is not False: + if cmd.is_generic(): + print("GENERIC COMMAND") + #return self.execute_generic_cmd(generic_cmd, args) + return self.execute_generic_cmd(cmd.name, cmd.args, cmd.devtype) + + # NATIVE command + ''' + if cmd.startswith('get_'): + #generic_cmd,_ = request[4:].split('(') + generic_cmd = cmd[4:] + if (generic_cmd not in self._cmd_getset.keys()) and (generic_cmd not in self._cmd_do.keys()): + #eval(request) + return self.get_radec() + print("cmd is", generic_cmd) + return self._get(generic_cmd) + return + ''' + # NATIVE command + print("NATIVE COMMAND") + #res_native = self.execute_native_cmd(raw_input_cmd) + res_native = self.execute_native_cmd(cmd.name_and_args) + return GenericResult(res_native) + + + #def execute_native_cmd(self, request:str, awaited_res_if_ok=None)->GenericResult: + def execute_native_cmd(self, native_cmd:str) -> str: + """ Execute a native command + + Args: + native_cmd: a native command + + Returns: + the command result + + """ + print("NATIVE Command to send is "+ repr(native_cmd)) + #self.send_request(native_cmd) + self.send_native_cmd(native_cmd) + native_res = self.receive_data() + return native_res + ''' + ok = True if not awaited_res_if_ok else (native_res == awaited_res_if_ok) + return GenericResult(native_res, ok) + ''' + + + ''' + def execute_native_cmd_OLD(self, request:str)->str: + self.send_request(request) + native_res = self.receive_data() + return native_res + ''' + + + def execute_unformated_native_cmd(self, request:str) -> str: + request = self.formated_cmd(request) + #return self.execute_native_cmd_OLD(request) + return self.execute_native_cmd(request) + + + def send_native_cmd(self, native_cmd:str)->str: + return self.send_data(native_cmd) + + + #@deprecated + def send_request(self, request:str)->str: + return self.send_native_cmd(request) + + + def print_available_commands(self): + print("\nAvailable commands are:") + print("- GET commands:") + #print (list(cmd.replace('_',' ') for cmd in self._cmd.keys() if cmd.startswith('get_'))) + print (list(cmd for cmd in self._cmd.keys() if cmd.startswith('get_'))) + print("- SET commands:") + print (list(cmd for cmd in self._cmd.keys() if cmd.startswith('set_'))) + print("- DO commands:") + print (list(cmd for cmd in self._cmd.keys() if cmd.startswith('do_'))) + + + def available_commands(self): + return list(self._cmd.keys()) + + + # @abstract + def formated_cmd(self, cmd:str, value:str=None)->str: + return cmd + + + #def run_func(self, func, arg=None): + def run_func(self, func, *args): + #print("args", args) + if args: + return getattr(self, func)(*args) + else: + return getattr(self, func)() + + ''' + TELESCOPE COMMANDS (abstract methods) + ''' + + #def execute_generic_cmd(self, generic_cmd:DeviceCommand)->str: + def execute_generic_cmd(self, generic_cmd:str, values_to_set:str=None, dc_component_type:str=None)->str: + ''' Execute a generic command + + :param generic_cmd: str like "get_ra" or "set_ra" or "do_park"... + :param value: only for a "set_" cmd + ''' + print("execute_generic_cmd() from", self) + # If generic_cmd is for a specific device component (dc), pass it to this dc (instead of me) + print("dc_component_type is: ", dc_component_type) + ####if dc_component_type and dc_component_type not in self.__class__.__name__ : + if dc_component_type: + dcc = self.get_dc_component_for_type(dc_component_type) + print("*** EXECUTÉ PAR COMPONENT", dcc) + #return (DCC)(self.execute_generic_cmd(generic_cmd, values_to_set, None)) + return dcc.execute_generic_cmd(generic_cmd, values_to_set, None) + + #log_d("\n\nGENERIC Command to send is "+generic_cmd) + print("\n\nGENERIC Command to send is ", generic_cmd) + print("My ("+type(self).__name__+") commands are:", self._cmd) + + if generic_cmd not in self._cmd: raise NotImplementedError + native_cmd_infos = self._cmd[generic_cmd] + # If this generic command has no corresponding native command, raise NotImplementedError + #if generic_cmd not in self._cmd.keys(): raise UnknownCommandException() + if not native_cmd_infos: raise NotImplementedError + # Get corresponding native command: + native_cmd = native_cmd_infos[0] + if not native_cmd: raise NotImplementedError + + # MACRO-COMMAND (ex: native_cmd == "do_goto", "do_init", "get_radec") + if native_cmd == generic_cmd: + print("MACRO-COMMAND") + #print("cmd,val", native_cmd, values_to_set) + #res:GenericResult = self.run_func(native_cmd, *values_to_set) + if values_to_set: + print("with args") + res = self.run_func(native_cmd, *values_to_set) + #res = getattr(self, native_cmd)(values_to_set) + else: + res = self.run_func(native_cmd) + #res = getattr(self, native_cmd)() + #if res is None: res = 'ok' + # res should be a GenericResult + if not isinstance(res, GenericResult): raise Exception("Should be a GenericResult", res) + return res + + # NATIVE COMMAND (ex: native_cmd == "GR") + native_cmd = self.formated_cmd(native_cmd, values_to_set) + awaited_res_if_ok = None + if len(native_cmd_infos) > 1: awaited_res_if_ok = native_cmd_infos[1] + #native_res = self.execute_native_cmd(self.formated_cmd(native_cmd,value), awaited_res_ok) + native_res = self.execute_native_cmd(native_cmd) + ok = True if not awaited_res_if_ok else (native_res == awaited_res_if_ok) + return GenericResult(native_res, ok) + + + + ''' + **************************** + **************************** + GENERIC TELESCOPE COMMANDS (abstract methods) + **************************** + **************************** + ''' + + + + ''' + **************************** + GENERIC GET & SET commands + **************************** + ''' + + + @generic_cmd + def get_timezone(self): pass + #def get_timezone(self): return self.execute_generic_cmd('get_timezone') + @generic_cmd + def set_timezone(self, hh): pass + #def set_timezone(self, hh): return self.execute_generic_cmd('set_timezone', hh) + + @generic_cmd + def get_date(self): pass + @generic_cmd + def set_date(self, mmddyy): pass + + @generic_cmd + def get_time(self): pass + @generic_cmd + def set_time(self, hhmmss): pass + + + + ''' + **************************** + GENERIC DO commands + **************************** + ''' + + # @abstract + #def do_INIT(self): return self._do("INIT") + + ''' do_PARK() (p103) + - STARTUP position = CWD + - :hC# + - position required for a Cold or Warm Start, pointing to the celestial pole of the given hemisphere (north or south), + with the counterweight pointing downwards (CWD position). From L4, V1.0 up + - HOME position parking => par defaut, c'est CWD, mais ca peut etre different + - :hP# + - defaults to the celestial pole visible at the given hemisphere (north or south) and can be set by the user + ''' + # @abstract + def do_PARK(self): pass + #def do_PARK(self): return self._do("PARK") + + # @abstract + def do_start(self): pass + def do_stop(self): pass + + # @abstract MACRO + def do_init(self): raise NotImplementedError + + + + + +# TODO: empecher de creer une instance de cette classe abstraite +# Avec ABC ? + +''' +if __name__ == "__main__": + + #HOST, PORT = "localhost", 9999 + #HOST, PORT = "localhost", 20001 + HOST, PORT = "localhost", 11110 + + # Classic usage: + #tsock = SocketClient_UDP_TCP(HOST, PORT, "UDP") + # More elegant usage, using "with": + with SocketClient_ABSTRACT(HOST, PORT, "UDP") as tsock: + + # 0) CONNECT to server (only for TCP, does nothing for UDP) + tsock._connect_to_server() + + while True: + + # 1) SEND REQUEST data to server + # saisie de la requête au clavier et suppression des espaces des 2 côtés + data = input("REQUEST TO SERVER [ex: ':GD#' (Get Dec), ':GR#' (Get RA)']: ").strip() + # test d'arrêt + if data=="": break + #data_to_send = bytes(data + "\n", "utf-8") + tsock.send_data(data) + #mysock.sendto("%s" % data, (HOST, PORT)) + #print("Sent: {}".format(data)) + + # 2) RECEIVE REPLY data from server + data_received = tsock.receive_data() + #reponse, adr = mysock.recvfrom(buf) + #print("Received: {}".format(data_received)) + #print("Useful data received: {}".format(data_useful)) + print('\n') + + #tsock.close() +''' \ No newline at end of file diff --git a/src/device_controller/abstract_component/filter_selector.py b/src/device_controller/abstract_component/filter_selector.py index 309df46..508cd1c 100755 --- a/src/device_controller/abstract_component/filter_selector.py +++ b/src/device_controller/abstract_component/filter_selector.py @@ -22,7 +22,7 @@ import src.core.celme as celme #from device_controller.abstract_component.base import * sys.path.append("../..") #from device_controller.abstract_component.base import * -from device_controller.abstract_component.base import DeviceControllerAbstract +from device_controller.abstract_component.device_controller import DeviceControllerAbstract # Default timeouts diff --git a/src/device_controller/abstract_component/telescope.py b/src/device_controller/abstract_component/telescope.py index 3b2d09a..c343fba 100755 --- a/src/device_controller/abstract_component/telescope.py +++ b/src/device_controller/abstract_component/telescope.py @@ -28,7 +28,7 @@ import src.core.celme as celme #sys.path.append('../..') #from src.client.socket_client_abstract import UnknownCommandException, SocketClientAbstract ##from src_socket.client.socket_client_abstract import * -from device_controller.abstract_component.base import * +from device_controller.abstract_component.device_controller import * diff --git a/src/device_controller/concrete_component/gemini/client_telescope_gemini_controller_run.py b/src/device_controller/concrete_component/gemini/client_telescope_gemini_controller_run.py index aa9e9fe..e801692 100755 --- a/src/device_controller/concrete_component/gemini/client_telescope_gemini_controller_run.py +++ b/src/device_controller/concrete_component/gemini/client_telescope_gemini_controller_run.py @@ -17,7 +17,7 @@ ou (3) sys.path.append("../../..") -from device_controller.abstract_component.base import DeviceCommand +from device_controller.abstract_component.device_controller import DeviceCommand #from gemini_telescope_controller import DeviceControllerTelescopeGemini from device_controller.concrete_component.gemini.gemini_telescope_controller import DeviceControllerTelescopeGemini diff --git a/src/device_controller/concrete_component/gemini/gemini_telescope_controller.py b/src/device_controller/concrete_component/gemini/gemini_telescope_controller.py index bab7382..01e9222 100755 --- a/src/device_controller/concrete_component/gemini/gemini_telescope_controller.py +++ b/src/device_controller/concrete_component/gemini/gemini_telescope_controller.py @@ -15,7 +15,7 @@ import time # Local application imports sys.path.append('../../..') -from device_controller.abstract_component.base import UnknownCommandException +from device_controller.abstract_component.device_controller import UnknownCommandException #from src.client.socket_client_telescope_abstract import Position, UnknownCommandException, TimeoutException, SocketClientTelescopeAbstract ##from src_socket.client.socket_client_telescope_abstract import * #from device_controller.abstract_component.telescope_controller_abstract import * diff --git a/src/device_controller/concrete_component/sbig/sbig_controller.py b/src/device_controller/concrete_component/sbig/sbig_controller.py index d02810f..03ca910 100755 --- a/src/device_controller/concrete_component/sbig/sbig_controller.py +++ b/src/device_controller/concrete_component/sbig/sbig_controller.py @@ -15,7 +15,7 @@ import time # Local application imports sys.path.append('../../..') -from device_controller.abstract_component.base import DeviceControllerAbstract, UnknownCommandException +from device_controller.abstract_component.device_controller import DeviceControllerAbstract, UnknownCommandException ''' from device_controller.abstract_component.detector_sensor import DeviceControllerDetectorSensor from device_controller.abstract_component.filter_selector import DeviceControllerFilterSelector diff --git a/src/device_controller/concrete_component/sbig/sbig_detector_sensor_controller.py b/src/device_controller/concrete_component/sbig/sbig_detector_sensor_controller.py index 4c5896a..31afa84 100755 --- a/src/device_controller/concrete_component/sbig/sbig_detector_sensor_controller.py +++ b/src/device_controller/concrete_component/sbig/sbig_detector_sensor_controller.py @@ -17,7 +17,7 @@ import time sys.path.append('../../..') from device_controller.abstract_component.detector_sensor import DeviceControllerDetectorSensor # TODO: AVIRER -from device_controller.abstract_component.base import UnknownCommandException +from device_controller.abstract_component.device_controller import UnknownCommandException # Default timeouts TIMEOUT_SEND = 10 diff --git a/src/device_controller/concrete_component/sbig/sbig_detector_shutter_controller.py b/src/device_controller/concrete_component/sbig/sbig_detector_shutter_controller.py index 59910e2..daf41f8 100755 --- a/src/device_controller/concrete_component/sbig/sbig_detector_shutter_controller.py +++ b/src/device_controller/concrete_component/sbig/sbig_detector_shutter_controller.py @@ -17,7 +17,7 @@ import time sys.path.append('../../..') from device_controller.abstract_component.detector_shutter import DeviceControllerDetectorShutter # TODO: AVIRER -from device_controller.abstract_component.base import UnknownCommandException +from device_controller.abstract_component.device_controller import UnknownCommandException # Default timeouts TIMEOUT_SEND = 10 diff --git a/src/device_controller/concrete_component/sbig/sbig_filter_selector_controller.py b/src/device_controller/concrete_component/sbig/sbig_filter_selector_controller.py index d539803..682c157 100755 --- a/src/device_controller/concrete_component/sbig/sbig_filter_selector_controller.py +++ b/src/device_controller/concrete_component/sbig/sbig_filter_selector_controller.py @@ -17,7 +17,7 @@ import time sys.path.append('../../..') from device_controller.abstract_component.filter_selector import DeviceControllerFilterSelector # TODO: AVIRER -from device_controller.abstract_component.base import UnknownCommandException +from device_controller.abstract_component.device_controller import UnknownCommandException # Default timeouts TIMEOUT_SEND = 10 -- libgit2 0.21.2