diff --git a/src/core/pyros_django/agent/Agent.py b/src/core/pyros_django/agent/Agent.py index d470500..73b1d7c 100755 --- a/src/core/pyros_django/agent/Agent.py +++ b/src/core/pyros_django/agent/Agent.py @@ -115,7 +115,7 @@ import config #from config import PYROS_ENV, ROOT_DIR, DOC_DIR #from config import * -from common.models import AgentSurvey, Command, AgentLogs +from common.models import AgentSurvey, AgentCmd, AgentLogs from config.configpyros import ConfigPyros #from dashboard.views import get_sunelev #from devices.TelescopeRemoteControlDefault import TelescopeRemoteControlDefault @@ -389,7 +389,7 @@ class Agent: _computer_description = '' # Current and next command to send - _cmdts:Command = None + _cmdts:AgentCmd = None _next_cmdts = None _agent_survey = None @@ -606,7 +606,7 @@ class Agent: # Avoid blocking on false "running" commands # (old commands that stayed with "running" status when agent was killed) - Command.delete_commands_with_running_status_for_agent(self.name) + AgentCmd.delete_commands_with_running_status_for_agent(self.name) self._iter_num = 1 self._DO_MAIN_LOOP = True @@ -715,7 +715,7 @@ class Agent: N=5 if ((self._iter_num-1) % N) == 0: self.print("Purging old commands if exists") - #Command.purge_old_commands_for_agent(self.name) + #AgentCmd.purge_old_commands_for_agent(self.name) self._purge_old_commands_sent_to_me() # Get next command and process it (if exists) @@ -778,14 +778,14 @@ class Agent: if self.TEST_MODE: self.printd("[IN TEST MODE]") self.print("Flush previous commands to be sure to start in clean state") - Command.delete_pending_commands_for_agent(self.name) + AgentCmd.delete_pending_commands_for_agent(self.name) else: self.printd("[IN NORMAL MODE]") self.TEST_MAX_DURATION_SEC=None def _purge_old_commands_sent_to_me(self): - Command.purge_old_commands_sent_to_agent(self.name) + AgentCmd.purge_old_commands_sent_to_agent(self.name) def _routine_process(self): @@ -822,14 +822,14 @@ class Agent: ### COMMAND_PEREMPTION_DATE_FROM_NOW = datetime.utcnow() - timedelta(hours = self.COMMANDS_PEREMPTION_HOURS) #self.printd("peremption date", COMMAND_PEREMPTION_DATE_FROM_NOW) - old_commands = Command.objects.filter( + old_commands = AgentCmd.objects.filter( # only commands for me recipient = self.name, # only pending commands sender_deposit_time__lt = COMMAND_PEREMPTION_DATE_FROM_NOW, ) ### - old_commands = Command.get_old_commands_for_agent(self.name) + old_commands = AgentCmd.get_old_commands_for_agent(self.name) if old_commands.exists(): self.printd("Found old commands to delete:") for cmd in old_commands: self.printd(cmd) @@ -1037,7 +1037,7 @@ class Agent: """ def send_command(self, cmd_name): recipient_agent = self.name if self.TEST_COMMANDS_DEST=="myself" else self.TEST_COMMANDS_DEST - Command.objects.create(sender=self.name, recipient=recipient_agent, name=cmd_name) + AgentCmd.objects.create(sender=self.name, recipient=recipient_agent, name=cmd_name) """ #def send_command(self, to_agent, cmd_type, cmd_name, cmd_args=None): def send_cmd_to(self, to_agent, cmd_name, cmd_args=None): @@ -1045,19 +1045,19 @@ class Agent: #ex: send_command(“AgentX”,”GENERIC”,”EVAL”,“3+4”) ex: send_command(“AgentX”,"EVAL”,“3+4”) """ - #return Command.send_cmd(self.name, self._get_real_agent_name_for_alias(to_agent), cmd_name, cmd_args) + #return AgentCmd.send_cmd(self.name, self._get_real_agent_name_for_alias(to_agent), cmd_name, cmd_args) cmd = self.create_cmd_for(to_agent, cmd_name, cmd_args) cmd.send() return cmd - def create_cmd_for(self, to_agent, cmd_name, cmd_args=None)->Command: + def create_cmd_for(self, to_agent, cmd_name, cmd_args=None)->AgentCmd: ''' real_agent_name = self._get_real_agent_name(to_agent) real_cmd_name = cmd_name if '.' in real_agent_name: real_agent_name, component_name = real_agent_name.split('.') real_cmd_name = component_name+'.'+cmd_name - return Command.create(self.name, real_agent_name, real_cmd_name, cmd_args) + return AgentCmd.create(self.name, real_agent_name, real_cmd_name, cmd_args) try: real_agent_name = self._get_real_agent_name(to_agent) except KeyError as e: @@ -1068,16 +1068,16 @@ class Agent: #self.log_e("Exception raised", e) self.log_e(f"=> Thus, I do not send this command '{cmd_name}'") return None - return Command.create(self.name, real_agent_name, cmd_name, cmd_args) + return AgentCmd.create(self.name, real_agent_name, cmd_name, cmd_args) ''' - return Command( + return AgentCmd( sender=self.name, recipient=self._get_real_agent_name_for_alias(recipient_agent_alias_name), name=cmd_name ) ''' - def _get_next_valid_and_not_running_command(self)->Command: + def _get_next_valid_and_not_running_command(self)->AgentCmd: """ Return next VALID (not expired) command (read from the DB command table) which is relevant to this agent. @@ -1091,13 +1091,13 @@ class Agent: # but there might be a risk # that a command status is modified while we are reading... with transaction.atomic(): - self._pending_commands = Command.get_pending_and_running_commands_for_agent(self.name) + self._pending_commands = AgentCmd.get_pending_and_running_commands_for_agent(self.name) commands = self._pending_commands if not commands.exists(): self.print("") return None self.printd("Current pending (or running) commands are (time ordered):") - Command.show_commands(commands) + AgentCmd.show_commands(commands) # 2) If there is a "do_exit" or "do_abort" command pending (even at the end of the list), # which is VALID (not expired), @@ -1165,7 +1165,7 @@ class Agent: #def _exec_agent_general_cmd(self, cmd:Command): - def _exec_agent_cmd(self, cmd:Command): + def _exec_agent_cmd(self, cmd:AgentCmd): #self.print(f"Starting execution of an AGENT LEVEL cmd {cmd}...") self.print(f"Starting execution of an AGENT LEVEL cmd...") @@ -1210,7 +1210,7 @@ class Agent: time.sleep(1) elif cmd_name in ("do_flush_commands"): self.printd("flush_commands received: Delete all pending commands") - Command.delete_pending_commands_for_agent(self.name) + AgentCmd.delete_pending_commands_for_agent(self.name) cmd.set_result('DONE') elif cmd_name in ("do_abort", "do_exit", "do_restart_init"): #self.printd("Current pending commands are:") @@ -1243,8 +1243,8 @@ class Agent: # This "do_exit" should normally kill any current thread (to be checked...) if cmd.name == "do_exit": self.print("Before exiting, Here are (if exists) the current (still) pending commands (time ordered) :") - commands = Command.get_pending_and_running_commands_for_agent(self.name) - Command.show_commands(commands, True) + commands = AgentCmd.get_pending_and_running_commands_for_agent(self.name) + AgentCmd.show_commands(commands, True) #if self.TEST_MODE and self.TEST_WITH_FINAL_TEST and self.TEST_COMMANDS_DEST == "myself": self.simulator_test_results() if self.TEST_MODE and self.TEST_WITH_FINAL_TEST: self._TEST_test_results() @@ -1264,14 +1264,14 @@ class Agent: self.printd("Logging data...") ''' - def exec_cmd_from_its_name(self, cmd:Command): + def exec_cmd_from_its_name(self, cmd:AgentCmd): func = cmd.name if cmd.args: return getattr(self, func)(*cmd.args) else: return getattr(self, func)() - def is_agent_level_cmd(self, cmd:Command): + def is_agent_level_cmd(self, cmd:AgentCmd): return cmd.is_agent_general_cmd() or self._is_agent_specific_cmd(cmd) ''' @@ -1292,7 +1292,7 @@ class Agent: self._exec_agent_specific_cmd(cmd) ''' - def _is_agent_specific_cmd(self, cmd:Command): + def _is_agent_specific_cmd(self, cmd:AgentCmd): return cmd.name in self.AGENT_SPECIFIC_COMMANDS ''' @@ -1318,12 +1318,12 @@ class Agent: # to be overriden by subclass (AgentDevice) # @abstract - def exec_device_cmd_if_possible(self, cmd:Command): + def exec_device_cmd_if_possible(self, cmd:AgentCmd): pass # TO BE OVERRIDEN by subclass (AgentDevice) # @abstract - def exec_device_cmd(self, cmd:Command): + def exec_device_cmd(self, cmd:AgentCmd): #self.exec_cmd_from_its_name(cmd) pass @@ -1344,7 +1344,7 @@ class Agent: def _set_test_mode(self, mode:bool): self.TEST_MODE=mode - def _TEST_get_next_command_to_send(self)->Command: + def _TEST_get_next_command_to_send(self)->AgentCmd: cmd_full_name = next(self.TEST_COMMANDS, None) #return cmd_name if cmd_full_name is None: return None @@ -1519,8 +1519,8 @@ class Agent: #commands = Command.get_last_N_commands_sent_to_agent(self.name, 16) nb_commands = len(self.TEST_COMMANDS_LIST) if "ad_unknown get_dec" in self.TEST_COMMANDS_LIST: nb_commands -= 1 - commands = Command.get_last_N_commands_sent_by_agent(self.name, nb_commands) - Command.show_commands(commands) + commands = AgentCmd.get_last_N_commands_sent_by_agent(self.name, nb_commands) + AgentCmd.show_commands(commands) return nb_commands, commands """ OLD SCENARIO nb_asserted = 0 diff --git a/src/core/pyros_django/agent/AgentDevice.py b/src/core/pyros_django/agent/AgentDevice.py index a1583b4..acb7e46 100755 --- a/src/core/pyros_django/agent/AgentDevice.py +++ b/src/core/pyros_django/agent/AgentDevice.py @@ -10,13 +10,13 @@ import time ##from .Agent import Agent sys.path.append("..") from agent.Agent import Agent, build_agent, StoppableThreadEvenWhenSleeping -from common.models import AgentDeviceStatus, Command, get_or_create_unique_row_from_model +from common.models import AgentDeviceStatus, AgentCmd, get_or_create_unique_row_from_model sys.path.append("../../..") from device_controller.abstract_component.device_controller import ( DeviceController, - DeviceCommand, + DeviceCmd, DeviceTimeoutException, UnknownGenericCmdException, UnimplementedGenericCmdException, DCCNotFoundException, UnknownNativeCmdException ) @@ -217,11 +217,11 @@ class AgentDevice(Agent): """ # @override superclass (Agent) method - def is_device_level_cmd(self, cmd:Command): - return self._device_ctrl.is_valid_cmd(DeviceCommand(cmd.full_name)) + def is_device_level_cmd(self, cmd:AgentCmd): + return self._device_ctrl.is_valid_cmd(DeviceCmd(cmd.full_name)) - def is_device_generic_but_UNIMPLEMENTED_cmd(self, cmd:Command): - return self._device_ctrl.is_generic_but_UNIMPLEMENTED_cmd(DeviceCommand(cmd.full_name)) + def is_device_generic_but_UNIMPLEMENTED_cmd(self, cmd:AgentCmd): + return self._device_ctrl.is_generic_but_UNIMPLEMENTED_cmd(DeviceCmd(cmd.full_name)) def _is_running_device_cmd(self): #return (self._current_device_cmd_thread is not None) or self._current_device_cmd_thread.is_alive() @@ -229,7 +229,7 @@ class AgentDevice(Agent): return self._current_device_cmd_thread and self._current_device_cmd_thread.is_alive() # @override superclass (Agent) method - def exec_device_cmd_if_possible(self, cmd:Command): + def exec_device_cmd_if_possible(self, cmd:AgentCmd): self._set_status(self.STATUS_SPECIFIC_PROCESS) #self.print(f"Starting execution of a DEVICE cmd {cmd}") @@ -567,7 +567,7 @@ class AgentDevice(Agent): # This method is also called DIRECTLY from routine_process().get_device_status() (NOT FROM A THREAD) # @override parent class (Agent) - def exec_device_cmd(self, cmd:Command): + def exec_device_cmd(self, cmd:AgentCmd): #cmd = self._current_device_cmd self.tprintd("*** DEVICE cmd name is", cmd.name) self.tprintd("*** PASS IT TO DEVICE TYPE", cmd.device_type) diff --git a/src/core/pyros_django/common/admin.py b/src/core/pyros_django/common/admin.py index 5dfb03d..04f8aca 100644 --- a/src/core/pyros_django/common/admin.py +++ b/src/core/pyros_django/common/admin.py @@ -233,7 +233,7 @@ class AlbumAdmin(PyrosModelAdmin): # Link the models to the admin interface # (EP added 10/7/19) -admin.site.register(Command) +admin.site.register(AgentCmd) admin.site.register(AgentLogs) admin.site.register(AgentSurvey) admin.site.register(AgentDeviceStatus) diff --git a/src/core/pyros_django/common/models.py b/src/core/pyros_django/common/models.py index 09fee0b..d250c95 100644 --- a/src/core/pyros_django/common/models.py +++ b/src/core/pyros_django/common/models.py @@ -17,7 +17,7 @@ from model_utils import Choices # Project imports # DeviceCommand is used by class Command sys.path.append("../../..") -from src.device_controller.abstract_component.device_controller import DeviceCommand +from src.device_controller.abstract_component.device_controller import DeviceCmd ''' NOT USED - to be removed @@ -401,7 +401,7 @@ class Alert(Request): -class Command(models.Model): +class AgentCmd(models.Model): """ | id | sender | recipient | name | validity_duration (default=60) | s_deposit_time | r_read_time @@ -539,7 +539,7 @@ class Command(models.Model): #s_deposit_time__gte = cls.get_peremption_date_from_now(), ) if running_commands: - Command.show_commands(running_commands) + AgentCmd.show_commands(running_commands) running_commands.delete() else: printd("") @@ -565,7 +565,7 @@ class Command(models.Model): s_deposit_time__lt = now_minus_2sec ) if pending_commands: - Command.show_commands(pending_commands) + AgentCmd.show_commands(pending_commands) pending_commands.delete() else: printd("") @@ -649,7 +649,7 @@ class Command(models.Model): else: printd("-", cmd.name, cmd) - # -------------- Command INSTANCE METHODS -------------- + # -------------- AgentCmd INSTANCE METHODS -------------- def __str__(self): #return (f"Commmand '{self.name}' ({self.state}) sent by agent {self.sender} to agent {self.recipient} at {self.s_deposit_time}") @@ -659,7 +659,7 @@ class Command(models.Model): @property def device_command(self): if not self._device_command: - self._device_command = DeviceCommand(self.full_name) + self._device_command = DeviceCmd(self.full_name) #dc = self._device_command #print("...DEVICE CMD:", dc.full_name, dc.name, dc.devtype, dc.args) return self._device_command diff --git a/src/core/pyros_django/monitoring/views.py b/src/core/pyros_django/monitoring/views.py index b5d6305..7e15470 100644 --- a/src/core/pyros_django/monitoring/views.py +++ b/src/core/pyros_django/monitoring/views.py @@ -1,6 +1,6 @@ from django.http import HttpResponse from django.shortcuts import render -from common.models import Command +from common.models import AgentCmd # Create your views here. @@ -41,7 +41,7 @@ def weather_config_update(request): # : ['monitor_name_switch', 'None', 'Came:/S/N_A5EM:/Power_input', 'Rain_boolean'] if "Error_code" in cmd_args: something = 5/0 - Command.send_command('Dashboard', 'AgentM', cmd_name, cmd_args) + AgentCmd.send_command('Dashboard', 'AgentM', cmd_name, cmd_args) #TODO: Pour l'instant, on ne recupere pas encore ce retour diff --git a/src/device_controller/abstract_component/device_controller.py b/src/device_controller/abstract_component/device_controller.py index 18fc79e..8129750 100755 --- a/src/device_controller/abstract_component/device_controller.py +++ b/src/device_controller/abstract_component/device_controller.py @@ -9,6 +9,7 @@ To be used as a base class (interface) for any concrete socket client telescope # Standard library imports #from enum import Enum import copy +from dataclasses import dataclass, field import functools #import inspect import logging @@ -18,6 +19,9 @@ import socket import sys import threading import time +from typing import Dict + + # Third party imports @@ -99,7 +103,7 @@ def recursive_search(f): return wrapped -class DeviceCommand: +class DeviceCmd: full_name:str = '' name = None @@ -141,7 +145,7 @@ class DeviceCommand: 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 DeviceCmd.is_generic_cmd_name(self.full_name) #return self.name.startswith('do_') or self.name.startswith('get_') or self.name.startswith('set_') ''' @@ -251,11 +255,8 @@ class UnexpectedCommandReturnCode(Exception): class DeviceTimeoutException(Exception): pass -#from dataclasses import dataclass, field -from typing import Dict -''' @dataclass class Cmd: generic_name: str = 'generic name' @@ -265,7 +266,6 @@ class Cmd: final_simul_response: str = 'simulator response' immediate_responses: Dict[str, str] = field(default_factory=dict) errors: Dict[str, str] = field(default_factory=dict) -''' class Gen2NatCmds: # To be set by constructor @@ -800,7 +800,7 @@ class DeviceController(): return dcc raise DCCNotFoundException("DEVICE CONTROLLER COMPONENT NOT FOUND: "+dc_component_type) - def is_valid_cmd(self, cmd:DeviceCommand): + def is_valid_cmd(self, cmd:DeviceCmd): self.printd("cmd.name is", cmd.name) self.printd(cmd) self.printd("generic ?", cmd.is_generic()) @@ -811,23 +811,23 @@ class DeviceController(): self.is_valid_native_cmd(cmd) ) - def is_generic_but_UNIMPLEMENTED_cmd(self, cmd:DeviceCommand): + def is_generic_but_UNIMPLEMENTED_cmd(self, cmd:DeviceCmd): return cmd.is_generic() and not self.is_implemented_generic_cmd(cmd) # WRAPPER methods - def has_generic_cmd(self, cmd:DeviceCommand): + def has_generic_cmd(self, cmd:DeviceCmd): #return self._my_cmds.get(cmd.name) is not None return cmd.name in self._my_cmds.get() - def has_native_cmd(self, cmd:DeviceCommand)->bool: + def has_native_cmd(self, cmd:DeviceCmd)->bool: #return self._my_cmds.get(cmd.name) is not None return self._my_cmds.has_native_cmd(cmd.name) - def has_native_cmd_for_generic(self, generic_cmd:DeviceCommand): + def has_native_cmd_for_generic(self, generic_cmd:DeviceCmd): return self._my_cmds.get_native_infos_for_generic_cmd(generic_cmd.name) not in [None, []] # check if generic cmd exists - def is_valid_generic_cmd(self, cmd:DeviceCommand): + def is_valid_generic_cmd(self, cmd:DeviceCmd): #printd("_my_cmds", self._my_cmds) # 1) If a DCC given, return search result in this DCC commands if cmd.devtype: @@ -849,7 +849,7 @@ class DeviceController(): ''' # check if generic cmd exists and is implemented as a native cmd (in dictionary) - def is_implemented_generic_cmd(self, cmd:DeviceCommand): + def is_implemented_generic_cmd(self, cmd:DeviceCmd): self.printd("is implemented generic ?") self.printd("cmd.devtype", cmd.devtype) #printd("_my_cmds", self._my_cmds) @@ -877,7 +877,7 @@ class DeviceController(): return self.get_dc_component_for_type(cmd.devtype).has_native_cmd_for_generic(cmd) ''' - def is_valid_native_cmd(self, cmd:DeviceCommand)->bool: + def is_valid_native_cmd(self, cmd:DeviceCmd)->bool: ##return self._my_cmds.is_valid_native_cmd(cmd.name) # 1) If a DCC given, return search result in this DCC commands if cmd.devtype: @@ -995,14 +995,14 @@ class DeviceController(): or - FROM A THREAD from AgentDevice._thread_exec_specific_cmd().exec_specific_cmd() ''' - #def execute_cmd(self, cmd:DeviceCommand)->GenericResult: + #def execute_cmd(self, cmd:DeviceCmd)->GenericResult: def exec_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) + cmd = DeviceCmd(raw_input_cmd) self.tprintd("cmd is", cmd, raw_input_cmd) # GENERIC command (pyros grammar) @@ -1176,7 +1176,7 @@ class DeviceController(): - #def exec_generic_cmd(self, generic_cmd:DeviceCommand)->str: + #def exec_generic_cmd(self, generic_cmd:DeviceCmd)->str: ##def exec_generic_cmd(self, generic_cmd:str, values_to_set:str=None, dcc_type:str=None)->str: def exec_generic_cmd(self, generic_cmd:str, values_to_set:str=None)->str: ''' Execute a generic command diff --git a/src/device_controller/concrete_component/gemini/gemini_controller.py b/src/device_controller/concrete_component/gemini/gemini_controller.py index 51b89e1..71e04c8 100755 --- a/src/device_controller/concrete_component/gemini/gemini_controller.py +++ b/src/device_controller/concrete_component/gemini/gemini_controller.py @@ -22,7 +22,7 @@ from device_controller.abstract_component.device_controller import ( printd, DeviceController, Gen2NatCmds, - #Cmd, + Cmd, UnknownNativeCmdException, UnknownGenericCmdArgException ) @@ -346,7 +346,6 @@ class DC_Gemini(DeviceController): # # VERSION 4 : Command class (Cmd) # - ''' get_ack2 = Cmd( #generic_name = 'get_ack2', @@ -370,7 +369,6 @@ class DC_Gemini(DeviceController): '1' : 'pb 1 ...', } ) - ''' # Utilisation, affichage -- libgit2 0.21.2