#!/usr/bin/env python3 import sys ##import utils.Logger as L #import threading #, multiprocessing, os #import time #from django.db import transaction #from common.models import Command sys.path.append("..") sys.path.append("../../../..") from src.core.pyros_django.agent.Agent import Agent, build_agent, log # PM 20190416 recycle code from src.core.pyros_django.devices.PLC import PLCController from src.core.pyros_django.monitoring.plc_checker import PlcChecker from common.models import * ##log = L.setupLogger("AgentXTaskLogger", "AgentX") class AgentM(Agent): # FOR TEST ONLY # Run this agent in simulator mode TEST_MODE = False # Run the assertion tests at the end TEST_WITH_FINAL_TEST = True TEST_MAX_DURATION_SEC = None #TEST_MAX_DURATION_SEC = 120 # PM 20190416 fucking config path starting: /home/patrick/Dev/PYROS/start_agent.py agentM ##_path_data = 'config' _path_data = 'config/old_config' # PM 20190416 recycle code plcController = PLCController() print ("AGENT ENV: config PLC is (ip={}, port={})".format(plcController.ip, plcController.port)) plc_checker = PlcChecker() log.debug("PLC instanciated") ''' # Who should I send commands to ? #TEST_COMMANDS_DEST = "myself" TEST_COMMANDS_DEST = "AgentA" # Scenario to be executed TEST_COMMANDS_LIST = [ "go_active", "go_idle", "go_active", "go_idle", "go_active", "go_idle", "exit", ] ''' """ ================================================================= FUNCTIONS RUN INSIDE MAIN THREAD ================================================================= """ # old config # @override #def __init__(self, name:str=None, config_filename=None, RUN_IN_THREAD=True): # def __init__(self, config_filename=None, RUN_IN_THREAD=True): # ##if name is None: name = self.__class__.__name__ # super().__init__(config_filename, RUN_IN_THREAD) # new config (obsconfig) def __init__(self, name:str=None, RUN_IN_THREAD=True): if name is None: name = self.__class__.__name__ super().__init__(RUN_IN_THREAD) # @override def init(self): super().init() log.debug("end init()") # --- Set the mode according the startmode value ##agent_alias = self.__class__.__name__ ##self.set_mode_from_config(agent_alias) ''' # @override def load_config(self): super().load_config() ''' ''' # @override def update_survey(self): super().update_survey() ''' ''' # @override def get_next_command(self): return super().get_next_command() ''' # @override def do_log(self): super().do_log() """ ================================================================= FUNCTIONS RUN INSIDE A SUB-THREAD (OR A PROCESS) (thread_*()) ================================================================= """ # Define your own command step(s) here def cmd_step1(self, step:int): cmd = self._current_specific_cmd cmd.result = f"in step #{step}/{self._thread_total_steps_number}" cmd.save() """ if self.RUN_IN_THREAD: print("(save from thread)") cmd.save() else: #@transaction.atomic print("(save from process)") with transaction.atomic(): cmd.save() #Command.objects.select_for_update() """ def cmd_step2(self, step:int): self.cmd_step1(step) def cmd_step3(self, step:int): self.cmd_step1(step) def cmd_step4(self, step:int): self.cmd_step1(step) """ # @override def thread_exec_specific_cmd_step(self, step:int, sleep_time:float=1.0): self.thread_stop_if_asked() cmd = self._current_specific_cmd print(f">>>>> Thread (cmd {cmd.name}): step #{step}/5") self.sleep(sleep_time) """ ''' # @override def exec_specific_cmd_start(self, cmd:Command, from_thread=True): super().exec_specific_cmd_start(cmd, from_thread) ''' # @override # previous name of function : routine_process # Note : in Agent.py, routine_process_body seems to be the main function of routine of the agent # We need to override routine_process_body and not routine_process def routine_process_body(self): log.debug("in routine_process_body()") print("TODO: we recycle code") status_plc = self.plcController.getStatus() if self.parseNewStatus(status_plc): self.saveWeather() #self.saveInternalMonitoring() def parseNewStatus(self,status_plc): # """ PM 20181009 parse new status for config # Find return string "plc_status" positin within status_plc if status_plc.find('PLC_STATUS') >= 0: self.plc_checker.chk_config(status_plc) return True return False def saveWeather(self): outside = WeatherWatch() inside = SiteWatch() datetimenow = datetime.now(timezone.utc) latest_entry_of_history = WeatherWatchHistory.objects.last() if latest_entry_of_history != None: # Get last entry of WeatherWatchHistory as WeatherWatch latest_entry_of_history_as_weather = WeatherWatch.objects.get(id=latest_entry_of_history.weather.id) for sensor in self.plc_checker.monitoring_names.keys(): if sensor in self.plc_checker.inside_sensors: value = self.plc_checker.get_sensor(sensor) inside.setAttribute(sensor,value) else: value = self.plc_checker.get_sensor(sensor) outside.setAttribute(sensor, value) outside.setGlobalStatus() outside.save() #inside.save() # We don't have an history for weatherwatch if latest_entry_of_history == None: weather_history = WeatherWatchHistory() weather_history.weather = outside for sensor in self.plc_checker.monitoring_names.keys(): weather_history.setAttribute(sensor,value) # save also sensors weather_history.save() else: time_between_history_and_latest_entry = datetimenow - latest_entry_of_history_as_weather.updated sec_diff = time_between_history_and_latest_entry.total_seconds() / 60 # if diff between last entry of history and current time if greather than x then we save a new entry in history # TODO: Rendre le 4 paramètrable -> configpyros if int(sec_diff) > 4: weather_history = WeatherWatchHistory() weather_history.weather = outside for sensor in self.plc_checker.monitoring_names.keys(): weather_history.setAttribute(sensor,value) weather_history.save() log.debug("saved weather") def isInsideMonitoring(self,key): print(key) if key in ("Power_input","Roof_state"): return True else: return False # @override def thread_exec_specific_cmd_main(self): # This is optional self.thread_set_total_steps_number(5) # HERE, write your own scenario # scenario OK self.thread_exec_specific_cmd_step(1, self.cmd_step1, 1) self.thread_exec_specific_cmd_step(2, self.cmd_step2, 3) self.thread_exec_specific_cmd_step(3, self.cmd_step1, 5) self.thread_exec_specific_cmd_step(4, self.cmd_step3, 10) self.thread_exec_specific_cmd_step(5, self.cmd_step1, 4) # ... as many as you need """ autre scenario self.thread_exec_specific_cmd_step(1, self.cmd_step1, 1) self.thread_exec_specific_cmd_step(2, self.cmd_step2, 2) self.thread_exec_specific_cmd_step(3, self.cmd_step1, 2) self.thread_exec_specific_cmd_step(4, self.cmd_step3, 2) self.thread_exec_specific_cmd_step(5, self.cmd_step1, 3) """ ''' # @override def exec_specific_cmd_end(self, cmd:Command, from_thread=True): super().exec_specific_cmd_end(cmd, from_thread) ''' if __name__ == "__main__": # with thread RUN_IN_THREAD=True # with process #RUN_IN_THREAD=False agent = build_agent(AgentM, RUN_IN_THREAD=RUN_IN_THREAD) ''' TEST_MODE, configfile = extract_parameters() agent = AgentM("AgentM", configfile, RUN_IN_THREAD) agent.setSimulatorMode(TEST_MODE) ''' print(agent) agent.run()