AgentM.py 5.96 KB
#!/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

# 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'
    # PM 20190416 recycle code
    plcController = PLCController()
    print ("AGENT ENV: config PLC is (ip={}, port={})".format(plcController.ip, plcController.port))
    plc_checker = PlcChecker()


    '''
    # 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
    =================================================================
    """

    # @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)

    # @override
    def init(self):
        super().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
    def routine_process(self):
        print("TODO: we recycle code")
        status_plc = self.plcController.getStatus()
        if self.parseNewStatus(status_plc):
            self.saveWeather()

    def parseNewStatus(self,status_plc):
        # """ PM 20181009 parse new status for config
        if status_plc.find('PLC_STATUS') >= 0:
            self.plc_checker.chk_config(status_plc)
            return True
        return False

    def saveWeather(self):
        outside = WeatherWatch()
        for sensor in self.plc_checker.monitoring_names.keys():
            value = self.plc_checker.get_sensor(sensor)
            print(sensor, value)
            outside.setAttribute(sensor, value)
        outside.setGlobalStatus()
        outside.save()

    # @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()