def RTC_error(self, error_1min):
            '''
            return False: si no se comprueba el RTC por error_1min
                          si no hay errores RTC
            return True:  si hay errores TRC 
                          
            '''

            # COMPRUEBO ERROR RTC SOLO SI NO HAY ERROR TX
            if error_1min: return False

            # DEVUELVO LOS VALORES DE last_fecha_data y last_hora_data asi como fecha_data y hora_data
            if self.redis.hexist(f'{self.DLGID}_ERROR',
                                 'last_fecha_data') & self.redis.hexist(
                                     f'{self.DLGID}_ERROR', 'last_hora_data'):
                last_fecha_data = self.redis.hget(f'{self.DLGID}_ERROR',
                                                  'last_fecha_data')
                last_hora_data = self.redis.hget(f'{self.DLGID}_ERROR',
                                                 'last_hora_data')
                fecha_data = read_param(self.DLGID, 'DATE')
                hora_data = read_param(self.DLGID, 'TIME')
                #
                # ACTUALIZO last_fecha_data Y last_hora_data CON LOS VALORES ACTUALES
                self.redis.hset(f'{self.DLGID}_ERROR', 'last_fecha_data',
                                fecha_data)
                self.redis.hset(f'{self.DLGID}_ERROR', 'last_hora_data',
                                hora_data)
            else:
                fecha_data = read_param(self.DLGID, 'DATE')
                hora_data = read_param(self.DLGID, 'TIME')
                last_fecha_data = fecha_data
                last_hora_data = hora_data
                #
                # ACTUALIZO last_fecha_data Y last_hora_data CON LOS VALORES ACTUALES
                self.redis.hset(f'{self.DLGID}_ERROR', 'last_fecha_data',
                                fecha_data)
                self.redis.hset(f'{self.DLGID}_ERROR', 'last_hora_data',
                                hora_data)
                #
                return False
            #
            # CHEQUEO QUE NO ESTE CAMBIANDO LA FECHA Y HORA
            if fecha_data == last_fecha_data and hora_data == last_hora_data:
                self.logs.print_inf(name_function, 'RTC ERROR')
                self.logs.dlg_performance(f'< RTC ERROR >')
                return True
            else:
                self.logs.print_inf(name_function, 'RTC OK')
                return False
Exemple #2
0
    def dlg_performance(self, message):

        # CREO EL OBJETO dlg_performance
        #dlg_performance = saved_logs('auto_dlg_performance', self.DLGID_CTRL)

        # OBTENGO LA FECHA DEL DLGID
        dlgid_date = read_param(self.DLGID_CTRL, 'DATE')

        # OBTENGO LA HORA DEL DLGID
        dlgid_time = read_param(self.DLGID_CTRL, 'TIME')

        # ESCRIBO EL LOGS
        self.script_performance.warning(
            f'[{dlgid_date}-{dlgid_time}] {message}')

        # ESCRIBO EL LOG FACIL EN CASO DE QUE ESTE HABILITADO
        if easy_log:
            # CREO EL OBJETO easy_dlg_performance_check   MER004_20200501.log
            #easy_dlg_performance_check = saved_logs(f'{self.DLGID_CTRL}_{system_date_raw}', self.DLGID_CTRL, f'{project_path}/{self.project_folder_name}/DLG_PERFORMANCE/')
            #
            # ESCRIBO EL LOGS
            self.easy_dlg_performance_check.write(
                f'[{dlgid_date}-{dlgid_time}] {message}')
    def delta_mag(self):
        '''
        Escribe en DLGID_CTRL/delta_ref_ref1 la diferencia entre las magnitudes de la referencia y la referencia 1
        '''

        name_function = 'DELTA_MAG'

        if (self.DLGID_REF_1 != '' and self.CHANNEL_REF_1 != ''):
            #
            mag_in_ref = float(read_param(self.DLGID_REF, self.CHANNEL_REF))
            mag_in_ref_1 = float(
                read_param(self.DLGID_REF_1, self.CHANNEL_REF_1))
            delta_ref1_ref = round(mag_in_ref_1 - mag_in_ref, 2)
            #
            # ESCRIBO EN REDIS LA DIFERENCIA
            self.redis.hset(self.DLGID_CTRL, 'delta_ref1_ref', delta_ref1_ref)
            #
            # IMPRIMO LOGS
            self.logs.print_out(name_function, 'delta_ref1_ref',
                                delta_ref1_ref)
        else:
            self.redis.hdel(self.DLGID_CTRL, 'delta_ref1_ref')
            self.logs.print_inf(name_function,
                                'NO HAY SISTEMA DE REFERENCIA 1')
        def readPlcMode():
            """
                lee el modo de trabajo en que actualmente se encuentra el tablero de control
                0 -> EMERGENCIA
                1 -> LOCAL
                2 -> REMOTO
            """

            # leo el modo en que actualmente esta trabajando el PLC
            MOD = read_param(self.DLGID_CTRL,'MOD')
            MOD = '102'       
            
            if MOD == "100": return "EMERGENCIA"
            elif MOD == "101": return "LOCAL"
            elif MOD == "102": return "REMOTO"
            else: 
                self.logs.print_error(name_function, 'MODO DE TRABAJO NO ADMITIDO: MOD = {0}'.format(MOD))
                self.logs.print_error(name_function, 'NO SE EJECUTA EL SCRIPT')
                quit()
    def show_pump1_state(self, channel_pump_name):
        #
        name_function = 'SHOW_PUMP1_STATE'
        #
        pump1_state = int(read_param(self.DLGID_CTRL, channel_pump_name))
        #
        if pump1_state == 1:
            self.redis.hset(self.DLGID_CTRL,
                            dic.get_dic('PUMP1_STATE', 'name'),
                            dic.get_dic('PUMP1_STATE', 'True_value'))
            self.logs.print_out(name_function,
                                dic.get_dic('PUMP1_STATE', 'name'),
                                dic.get_dic('PUMP1_STATE', 'True_value'))

        elif pump1_state == 0:
            self.redis.hset(self.DLGID_CTRL,
                            dic.get_dic('PUMP1_STATE', 'name'),
                            dic.get_dic('PUMP1_STATE', 'False_value'))
            self.logs.print_out(name_function,
                                dic.get_dic('PUMP1_STATE', 'name'),
                                dic.get_dic('PUMP1_STATE', 'False_value'))
Exemple #6
0
def control_process(LIST_CONFIG):
    ''''''

    name_function = 'CONTROL_PROCESS'

    conf = config_var(LIST_CONFIG)

    # VARIABLES DE EJECUCION
    DLGID_CTRL = conf.lst_get('DLGID_CTRL')
    TYPE = conf.lst_get('TYPE')
    print_log = str2bool(conf.lst_get('print_log'))
    LOG_LEVEL = conf.lst_get('LOG_LEVEL')

    #VARIABLES DE CONFIGURACION
    ENABLE_OUTPUTS = str2bool(conf.lst_get('ENABLE_OUTPUTS'))
    TYPE_IN_FREC = conf.lst_get('TYPE_IN_FREC')
    DLGID_REF = conf.lst_get('DLGID_REF')
    CHANNEL_REF = conf.lst_get('CHANNEL_REF')
    DLGID_REF_1 = conf.lst_get('DLGID_REF_1')
    CHANNEL_REF_1 = conf.lst_get('CHANNEL_REF_1')

    ## INSTANCIAS
    logs = ctrl_logs(TYPE, 'CTRL_FREC_process', DLGID_CTRL, print_log,
                     LOG_LEVEL)
    config = configparser.ConfigParser()
    redis = Redis()
    #gda = GDA(serv_APP_config['CONFIG']['working_mode'])

    redis.no_execution('MER004')
    '''
    # INSTANCIA DE error_process
    import importlib.util
    #spec = importlib.util.spec_from_file_location("archivo", f"../{TYPE}/PROCESS/ctrl_library.py")
    spec = importlib.util.spec_from_file_location("archivo", f"/datos/cgi-bin/spx/AUTOMATISMOS/{TYPE}/PROCESS/ctrl_library.py")
    archivo = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(archivo)
    p = archivo.ctrl_process(LIST_CONFIG)'''

    p = ctrlProcess(LIST_CONFIG)

    # OBTENFO LA CARPETA EN DONDE SE ENCUENTRA EL ARCHIVO ACTUAL
    current_path = os.path.dirname(os.path.abspath(__file__))
    # LEO EL ARCHIVO DE CONFIGURACION
    config.read(f"{current_path}/ctrl_config.ini")

    #---------------------------------------------------------
    ##PROCESS

    logs.basicLog(__doc__)

    # ESCRIBO LA EJECUCION DEL SCRIPT
    logs.print_log(f"{name_function}")

    #logs.script_performance(f"{name_function}")

    # MUESTRO VARIABLES DE ENTRADA
    logs.print_in(name_function, 'print_log', print_log)
    logs.print_in(name_function, 'DLGID_CTRL', DLGID_CTRL)
    logs.print_in(name_function, 'TYPE', TYPE)
    logs.print_in(name_function, 'ENABLE_OUTPUTS', ENABLE_OUTPUTS)
    logs.print_in(name_function, 'TYPE_IN_FREC', TYPE_IN_FREC)
    logs.print_in(name_function, 'DLGID_REF', DLGID_REF)
    logs.print_in(name_function, 'CHANNEL_REF', CHANNEL_REF)
    logs.print_in(name_function, 'DLGID_REF_1', DLGID_REF_1)
    logs.print_in(name_function, 'CHANNEL_REF_1', CHANNEL_REF_1)

    # ESCRIBO NUMERO DE EJECUCION
    #redis.no_execution(DLGID_CTRL)

    # CHEQUEO QUE EXISTAN LOS LINES DEL DATALOGGER DE CONTROL Y EL DE REFERENCIA.
    if not (redis.hexist(DLGID_CTRL, 'LINE')):
        #logs.script_performance(f'{name_function} ==> NO EXISTE LINE {DLGID_CTRL}')
        logs.print_inf(name_function, f'NO EXISTE LINE {DLGID_CTRL}')
        logs.print_inf(name_function, 'EJECUCION INTERRUMPIDA')
        quit()

    if not (redis.hexist(DLGID_REF, 'LINE')):
        #logs.script_performance(f'NO EXISTE LINE {DLGID_REF}')
        logs.print_inf(name_function, f'NO EXISTE LINE {DLGID_REF}')
        logs.print_inf(name_function, 'EJECUCION INTERRUMPIDA')
        quit()

    #
    logs.print_inf(name_function, 'CHEQUEO_ALARMAS')
    p.chequeo_alarmas()
    #
    #logs.print_inf(name_function, 'CHEQUEO_SENSOR')
    #p.chequeo_sensor()
    #
    logs.print_inf(name_function, 'MAIN')

    # FUNCION MAIN
    name_function = 'MAIN'

    # CONDICIONES INICIALES
    #
    ## ACTIVO BANDERA PARA QUE control_error NOTIFIQUE QUE SE ESTA TRABAJANDO CON REFERENCIA_1
    redis.hset(DLGID_CTRL, 'flag_work_syst_ref_1', 'NO')

    # REVISO SI ESTA TRABAJANDO EN MODO LOCAL EN EL TABLERO
    if read_param(DLGID_CTRL, 'LM') == '1':
        logs.print_inf(name_function, 'TRABAJO EN MODO LOCAL')
        redis.hset(DLGID_CTRL, 'LOCAL_MODE', 'SI')
    elif read_param(DLGID_CTRL, 'LM') == '0':
        redis.hset(DLGID_CTRL, 'LOCAL_MODE', 'NO')  #VISUALIZACION
        #
        # SI NO EXISTE LA VARIABLE DE SELECCION SW1 LA CREO CON VALOR AUTO
        if not (redis.hexist(DLGID_CTRL, dic.get_dic('WEB_MODE', 'name'))):
            redis.hset(DLGID_CTRL, dic.get_dic('WEB_MODE', 'name'),
                       dic.get_dic('WEB_MODE', 'True_value'))
            # MUESTRO LOGS DE ADVERTENCIA
            logs.print_inf(name_function, 'NO EXISTE LA VARIABLE SW1 EN REDIS')
            logs.print_inf(
                name_function, 'SE CREA LA VARIABLE CON VALOR [0]'.format(
                    dic.get_dic('WEB_MODE', 'True_value')))
            #logs.script_performance('error in [0] [1] = ,'.format(name_function,dic.get_dic('WEB_MODE', 'name')))
            #logs.script_performance('error in [0], SE CREA [1] = [2]'.format(name_function,dic.get_dic('WEB_MODE', 'name'),dic.get_dic('WEB_MODE', 'True_value')))
        #
        # LEO VAERIABLE WEB_MODE
        WEB_MODE = redis.hget(DLGID_CTRL, dic.get_dic('WEB_MODE', 'name'))

        # REVISO EL MODO DE TRABAJO WEB
        if WEB_MODE == 'REMOTO':
            logs.print_inf(name_function, 'TRABAJO EN MODO REMOTO')
            p.modo_remoto()

        elif WEB_MODE in [
                dic.get_dic('WEB_MODE', 'value_1'),
                dic.get_dic('WEB_MODE', 'value_1'),
        ]:
            logs.print_inf(name_function,
                           'TRABAJO EN MODO SISTEMA DE EMERGENCIA')
            # REVISO EL ESTADO DE ENABLE_OUTPUTS
            if ENABLE_OUTPUTS:
                emerg_system(DLGID_CTRL)
            else:
                logs.print_inf(
                    name_function,
                    f"SALIDAS DESCACTIVADAS [ENABLE_OUTPUTS = {ENABLE_OUTPUTS}]"
                )
                #logs.script_performance(f"{name_function} ==> SALIDAS DESCACTIVADAS [ENABLE_OUTPUTS = {ENABLE_OUTPUTS}]")

        elif WEB_MODE == 'AUTO':
            logs.print_inf(name_function, 'TRABAJO EN MODO AUTOMATICO')
            #
            # SI NO EXISTE LA VARIABLE TX_ERROR EN DLGID_REF LA CREO CON VALOR NO
            if not (redis.hexist(DLGID_REF, dic.get_dic('TX_ERROR', 'name'))):
                redis.hset(DLGID_REF, dic.get_dic('TX_ERROR', 'name'),
                           dic.get_dic('TX_ERROR', 'False_value'))
            #
            # LEO MAG_REF SELECCIONADA POR EL CLIENTE. SI NO EXISTE LMIN LO CREO CON VALOR 1
            if not (redis.hexist(DLGID_CTRL, dic.get_dic('MAG_REF', 'name'))):
                redis.hset(DLGID_CTRL, dic.get_dic('MAG_REF', 'name'),
                           dic.get_dic('MAG_REF', 'True_value'))
            else:
                MAG_REF = float(
                    redis.hget(DLGID_CTRL, dic.get_dic('MAG_REF', 'name')))

            # LEO TX_ERROR Y # error_1min
            TX_ERROR = redis.hget(DLGID_REF, dic.get_dic('TX_ERROR', 'name'))
            error_1min = redis.hget(DLGID_REF, 'error_1min')

            # CHEQUEO ERROR TX EN EL DLG DE REFERENCIA (SE DECLARA ERROR_TX CUANDO PASAN 10 MIN SIN TRANSMITIR)
            if TX_ERROR == 'SI':
                logs.print_inf(
                    name_function,
                    f'ERROR TX EN SISTEMA DE REFERENCIA [ {DLGID_REF} ]')
                #logs.print_inf(name_function, 'AUTOMATISMO TRABAJADO CON SISTEMA DE EMERGENCIA')
                #
                # CHEQUEO QUE SE HAYA ESCRITO LA DIFERENCIA EN MAGNITUD ENTRE LOS SENSORES
                if redis.hexist(DLGID_CTRL, 'delta_ref1_ref'):
                    #
                    # LEO LA DIFERENCIA ENTRE LAS MAGNITUDES DE REFERENCIA
                    delta_ref1_ref = float(
                        redis.hget(DLGID_CTRL, 'delta_ref1_ref'))
                    #
                    # CHEQUEO EL ESTADO DEL SENSOR DE REFERENCIA 1
                    if not (p.chequeo_sensor(DLGID_REF_1, CHANNEL_REF_1)):
                        logs.print_inf(
                            name_function,
                            'ERROR DE SENSOR EN SISTEMA DE REFERENCIA 1')
                        logs.print_inf(
                            name_function,
                            'AUTOMATISMO TRABAJADO CON SISTEMA DE EMERGENCIA')
                        emerg_system(DLGID_CTRL)
                    else:
                        logs.print_inf(
                            name_function,
                            'AUTOMATISMO TRABAJADO CON SISTEMA DE REFERENCIA 1'
                        )
                        #
                        # ACTIVO BANDERA PARA QUE control_error NOTIFIQUE QUE SE ESTA TRABAJANDO CON REFERENCIA_1
                        redis.hset(DLGID_CTRL, 'flag_work_syst_ref_1', 'SI')
                        #
                        # LLAMO AL CONTROL DEL SISTEMA
                        p.control_sistema(DLGID_REF_1, CHANNEL_REF_1,
                                          MAG_REF + delta_ref1_ref)
                #
                else:
                    logs.print_inf(
                        name_function,
                        'AUTOMATISMO TRABAJADO CON SISTEMA DE EMERGENCIA')
                    emerg_system(DLGID_CTRL)

            elif TX_ERROR == 'NO':
                # ME ASEGURO QUE LA REFENCIA ME HAYA MANDADO UN DATO NUEVO
                if error_1min == 'NO':
                    # CHEQUEO ERROR EN EL SENSOR
                    if not (p.chequeo_sensor(DLGID_REF, CHANNEL_REF)):
                        logs.print_inf(
                            name_function,
                            'ERROR DE SENSOR EN SISTEMA DE REFERENCIA')
                        logs.print_inf(
                            name_function,
                            'AUTOMATISMO TRABAJADO CON SISTEMA DE EMERGENCIA')
                        #
                        emerg_system(DLGID_CTRL)
                    else:
                        logs.print_inf(name_function, 'CONTROL_SISTEMA')
                        p.control_sistema(DLGID_REF, CHANNEL_REF, MAG_REF)
                        #
                        logs.print_inf(name_function, 'DELTA_MAG')
                        p.delta_mag()
                else:
                    logs.print_inf(name_function,
                                   'EN ESPERA DE DATOS DE LA REFERENCIA')

            else:
                logs.print_inf(
                    name_function, "error in [0], [1] = [2]".format(
                        name_function, dic.get_dic('TX_ERROR', 'name'),
                        TX_ERROR))
                # DEJAR REGISTRO DEL ERROR
                #logs.script_performance("error in [0], [1] = [2]".format(name_function,dic.get_dic('TX_ERROR', 'name'),TX_ERROR))
            #
        else:
            logs.print_inf(
                name_function, 'error in [0], [1] = [2]'.format(
                    name_function, dic.get_dic('WEB_MODE', 'name'), WEB_MODE))
            # DEJAR REGISTRO DEL ERROR
            #logs.script_performance('error in [0], [1] = [2]'.format(name_function,dic.get_dic('WEB_MODE', 'name'),WEB_MODE))

    else:
        logs.print_inf(
            name_function,
            f"error in {name_function}, LM = {read_param(DLGID_CTRL,'LM')}")
        logs.print_inf(name_function, 'EJECUCION INTERRUMPIDA')
        # DEJAR REGISTRO DEL ERROR
        #logs.script_performance(f"error in {name_function}, LM = {read_param(DLGID_CTRL,'LM')}")

    # LATCHEO LAS SALIDAS
    p.latch__outpust(DLGID_CTRL)

    # PREPARO DATA_DATE_TIME PARA MOSTRAR EN LA VISUALIZACION EN EL DATALOGGER DE CONTROL
    logs.print_inf(name_function, 'SHOW_DATA_DATE_TIME')
    p.show_DATA_DATE_TIME(DLGID_CTRL)

    # PREPARO DATA_DATE_TIME PARA MOSTRAR EN LA VISUALIZACION EN EL DATALOGGER DE REFERENCIA
    p.show_DATA_DATE_TIME(DLGID_REF)

    # PREPARO PUMP1_STATE PARA MOSTRAR EL ESTADO DE LA BOMBA
    logs.print_inf(name_function, 'SHOW_PUMP1_STATE')
    p.show_pump1_state('BR1')

    # MUESTRA LA FRECUENCIA ACTUAL A LA QUE SE ESTA TRABAJANDO
    logs.print_inf(name_function, 'SHOW_WORK_FREQUENCY')
    p.show_work_frequency()
    def getAndUpdateMode(self,WEB_Mode):
        '''
            funcion para obtener el modo de trabajo y actualizarlo en caso necesario
        '''
        name_function = 'GET_AND_UPDATE_MODE'

        # entradas
        self.logs.print_in(name_function, 'WEB_Mode', WEB_Mode)

        def readPlcMode():
            """
                lee el modo de trabajo en que actualmente se encuentra el tablero de control
                0 -> EMERGENCIA
                1 -> LOCAL
                2 -> REMOTO
            """

            # leo el modo en que actualmente esta trabajando el PLC
            MOD = read_param(self.DLGID_CTRL,'MOD')
            MOD = '102'       
            
            if MOD == "100": return "EMERGENCIA"
            elif MOD == "101": return "LOCAL"
            elif MOD == "102": return "REMOTO"
            else: 
                self.logs.print_error(name_function, 'MODO DE TRABAJO NO ADMITIDO: MOD = {0}'.format(MOD))
                self.logs.print_error(name_function, 'NO SE EJECUTA EL SCRIPT')
                quit()

        def IsWebModeChanged():
            """
                detecta si hubo un cambio en el modo de trabajo web
            """
            if not self.redis.hexist(self.DLGID_CTRL,'Last_WEB_Mode'):
                self.redis.hset(self.DLGID_CTRL,'Last_WEB_Mode',WEB_Mode)
            
            Last_WEB_Mode = self.redis.hget(self.DLGID_CTRL,'Last_WEB_Mode')

            if Last_WEB_Mode != WEB_Mode:
                self.redis.hset(self.DLGID_CTRL,'Last_WEB_Mode',WEB_Mode)
                return True
            else:
                return False

        def setToPlcMode(WEB_Mode):
            """
                se escribe el registro UMOD del PLC para que el mismo actualice el modo
            """
            if WEB_Mode == "EMERGENCIA":
                mbusWrite(self.DLGID_CTRL,'2097','interger',105)
            elif WEB_Mode == "REMOTO":
                mbusWrite(self.DLGID_CTRL,'2097','interger',107)
            else:
                pass

        def IsPlcModeUpdated():
            """
                se compara el modo de trabajo de la web con el modo actual de trabajo del PLC.
                Si son iguales se retorna true, en caso contrario false
            """
            plcMode = readPlcMode()

            if plcMode != "LOCAL":
                if WEB_Mode == plcMode:
                    return True 
                else:
                    return False 
            else:
                # el plc esta trabajando en modo local por lo que no se puede decir que este desactualizado con la web 
                # ya que la misma no trabaja en este modo
                # se asume que estan actualizados
                return True
            
        def updateWebMode(UMOD):
            """
                Se actualiza en la web el modo de la siguiente forma
                101-> EMERGENCIA
                103-> LOCAL
                103-> REMOTO
                En caso de valor 102 return True para indicar que se esta trabajando en modo local
            """
            if UMOD == "101":
                self.logs.print_inf(name_function,"SE ACTUALIZA EL MODO EN LA WEB")
                self.gda.WriteAutConf(self.DLGID_CTRL,'WEB_Mode','EMERGENCIA')
                self.redis.hset(self.DLGID_CTRL,'Last_WEB_Mode','EMERGENCIA')
                mbusWrite(self.DLGID_CTRL,'2097','interger',100)
            elif UMOD == "102":
                self.logs.print_inf(name_function,"MODO LOCAL EN EL TABLERO")
                self.logs.print_inf(name_function,"NO SE TIENE CONTROL REMOTO")
            elif UMOD == "103":
                self.logs.print_inf(name_function,"SE ACTUALIZA EL MODO EN LA WEB")
                self.gda.WriteAutConf(self.DLGID_CTRL,'WEB_Mode','REMOTO')
                self.redis.hset(self.DLGID_CTRL,'Last_WEB_Mode','REMOTO')
                mbusWrite(self.DLGID_CTRL,'2097','interger',100)

        def IsUpdatePlcModePending():
            '''
               retorna true en caso de haber pendiente una actualizacion de modo hacia el PLC
            '''        
            if self.redis.hexist(self.DLGID_CTRL,'UpdatePlcModePending'):
                UpdatePlcModePending  = self.redis.hget(self.DLGID_CTRL,'UpdatePlcModePending')
            else:
                self.redis.hset(self.DLGID_CTRL,'UpdatePlcModePending','NO')
                UpdatePlcModePending = 'NO'

            if UpdatePlcModePending == 'SI': 
                return True
            else: 
                return False


            
        # MAIN
        # actualizo el modo para el software a partir del modo en que se encuentra el plc
        SOFT_Mode = readPlcMode()
        self.logs.print_in(name_function, 'MOD', SOFT_Mode)

        if IsWebModeChanged():
            self.logs.print_inf(name_function,"HUBO CAMBIO DE MODO EN LA WEB")
            
            # mando a escribir el modo al plc
            self.logs.print_inf(name_function,"SE MANDA A ACTUALIZAR EL MODO EN EL PLC")
            setToPlcMode(WEB_Mode)

            # activo una bandera para idicar que se esta en un proceso de cambio de modo hacia el PLC
            self.redis.hset(self.DLGID_CTRL,'UpdatePlcModePending','SI')

        else:
            # verifico que este en proceso una actualizacion de modo en el plc
            if IsUpdatePlcModePending():
                # chequeo si se actualizo el modo del PLC. Si no lo hizo lo vuelvo a escribir.
                self.logs.print_inf(name_function,"PROCESO DE ACTUALIZACION DE MODO HACIA EL PLC PENDIENTE")
                if not IsPlcModeUpdated():
                    self.logs.print_inf(name_function,"SE MANDA NUEVAMENTE!!! A ACTUALIZAR EL MODO EN EL PLC")
                    setToPlcMode(WEB_Mode)
                else:
                    self.logs.print_inf(name_function,"MODO EN EL PLC ACTUALIZADO DE FORMA CORRECTA")
                    self.redis.hset(self.DLGID_CTRL,'UpdatePlcModePending','NO')
            else:
                # chequep si hay pedido para actualizar en la web
                UMOD = read_param(self.DLGID_CTRL,'UMOD')
                #UMOD = '101'
                if UMOD == '100':
                    self.logs.print_inf(name_function,"MODOS DE TRABAJO ACTUALIZADOS")
                elif UMOD in ['101','102','103']:
                    # Actualizo el modo web
                    self.logs.print_inf(name_function,"HUBO CAMBIO DE MODO EN EL PLC")
                    updateWebMode(UMOD)
                else:
                    self.logs.print_error(name_function,"VALOR NO ADMITIDO PARA ACTUALIZACION DE MODOS: UMOD = {0}".format(UMOD))
                    self.logs.print_error(name_function,"SE IGNORA ESTE VALOR")

        self.logs.print_out(name_function, 'SOFT_Mode', SOFT_Mode)
        return SOFT_Mode
 def test_tx(self):
     '''
     detecta errores tx y RTC
     return '' =>     si no existe el line del datalogger
     return False =>  si hay errores TX de cualquier tipo
     return True =>   cualquier otra opcion
     '''
     
     name_function = 'TEST_TX_ERRORS'
     
     # CHEQUEO DE ERROR TX
     #
     
     # CHEQUEO SI EXISTE EL LINE EN EL DATALOGGER
     if not(self.redis.hexist(self.DLGID, 'LINE')):
         return 'noLine'
     
     # DEVUELVO last_line CON EL LINE ANTERIOR Y current_line CON EL LINE ACTUAL
     if self.redis.hexist(f'{self.DLGID}_ERROR', 'last_line'):
         last_line = self.redis.hget(f'{self.DLGID}_ERROR', 'last_line')
         current_line = self.redis.hget(self.DLGID, 'LINE')
         self.redis.hset(f'{self.DLGID}_ERROR', 'last_line', current_line)
     else:
         last_line = self.redis.hget(self.DLGID, 'LINE')
         self.redis.hset(f'{self.DLGID}_ERROR', 'last_line', last_line)
         current_line = last_line
         return True
         
     # ASIGNO EL VALOR DE LA BATERIA PARA MOSTRARLO EN LOS LOGS
     if read_param(self.DLGID, 'BAT'):
         bat = read_param(self.DLGID, 'BAT')
     else:
         bat = read_param(self.DLGID, 'bt')
     
     
     
     def error_1min_TX(self):
         '''
         return True si hubo error de TX durante un minuto
         return False si no hubo error de TX durante un minuto
         '''
         
         if last_line == current_line:
             #
             return True
         else:
             #
             self.logs.print_inf(name_function, 'TX OK')
             #
             return False
     
     def RTC_error(self,error_1min):
         '''
         return False: si no se comprueba el RTC por error_1min
                       si no hay errores RTC
         return True:  si hay errores TRC 
                       
         '''
         
         # COMPRUEBO ERROR RTC SOLO SI NO HAY ERROR TX
         if error_1min: return False
             
         # DEVUELVO LOS VALORES DE last_fecha_data y last_hora_data asi como fecha_data y hora_data
         if self.redis.hexist(f'{self.DLGID}_ERROR', 'last_fecha_data') & self.redis.hexist(f'{self.DLGID}_ERROR', 'last_hora_data'):
             last_fecha_data = self.redis.hget(f'{self.DLGID}_ERROR', 'last_fecha_data')
             last_hora_data = self.redis.hget(f'{self.DLGID}_ERROR', 'last_hora_data')
             fecha_data = read_param(self.DLGID, 'DATE')
             hora_data = read_param(self.DLGID, 'TIME')
             #
             # ACTUALIZO last_fecha_data Y last_hora_data CON LOS VALORES ACTUALES
             self.redis.hset(f'{self.DLGID}_ERROR', 'last_fecha_data', fecha_data)
             self.redis.hset(f'{self.DLGID}_ERROR', 'last_hora_data', hora_data)
         else:
             fecha_data = read_param(self.DLGID, 'DATE')
             hora_data = read_param(self.DLGID, 'TIME')
             last_fecha_data = fecha_data
             last_hora_data = hora_data
             #
             # ACTUALIZO last_fecha_data Y last_hora_data CON LOS VALORES ACTUALES
             self.redis.hset(f'{self.DLGID}_ERROR', 'last_fecha_data', fecha_data)
             self.redis.hset(f'{self.DLGID}_ERROR', 'last_hora_data', hora_data)
             #
             return False
         #
         # CHEQUEO QUE NO ESTE CAMBIANDO LA FECHA Y HORA
         if fecha_data == last_fecha_data and hora_data == last_hora_data:
             self.logs.print_inf(name_function, 'RTC ERROR')
             self.logs.dlg_performance(f'< RTC ERROR >')
             return True
         else:
             self.logs.print_inf(name_function, 'RTC OK')
             return False
     
     def error_10min_TX(self,error_1min):
         '''
         return True si hubo error de TX durante mas 10 minuto
         return False si se restablece la cominicacion
         '''
         
         if error_1min:
             # INICIALIZO EL CONTADOR DE MINUTOS CON ERORR TX 
             if not(self.redis.hexist(f'{self.DLGID}_ERROR','count_error_tx')):
                 self.redis.hset(f'{self.DLGID}_ERROR', 'count_error_tx', 1)
             
             # LEO EL CONTADOS DE TIEMPO
             count_error_tx = int(self.redis.hget(f'{self.DLGID}_ERROR','count_error_tx'))
             
             # VEO EL ESTADO DEL CONTADOR    
             if count_error_tx >= 10:
                 #
                 return True
             else:
                 self.logs.print_inf(name_function, f'CONTADOR DE ERROR TX [{count_error_tx}]')
                 count_error_tx += 1
                 self.redis.hset(f'{self.DLGID}_ERROR','count_error_tx',count_error_tx)
                 #   
                 return False
         else:
             if self.redis.hexist(f'{self.DLGID}_ERROR','count_error_tx'):
                 self.redis.hdel(f'{self.DLGID}_ERROR','count_error_tx')   
             #
             return False
         
     def error_TPOLL_TX(self,timer_poll,error_1min):
         
         '''
         return True si hubo error de TX durante mas TPOLL minutos
         return False si se restablece la cominicacion
         '''
         
         if error_1min:
             # INICIALIZO EL CONTADOR DE MINUTOS CON ERORR TX 
             if not(self.redis.hexist(f'{self.DLGID}_ERROR','count_error_tx')):
                 self.redis.hset(f'{self.DLGID}_ERROR', 'count_error_tx', 1)
             
             # LEO EL CONTADOS DE TIEMPO
             count_error_tx = int(self.redis.hget(f'{self.DLGID}_ERROR','count_error_tx'))
             
             # VEO EL ESTADO DEL CONTADOR    
             if count_error_tx >= timer_poll:
                 #
                 return True
             else:
                 self.logs.print_inf(name_function, f'CONTADOR DE ERROR TX [{count_error_tx}]')
                 count_error_tx += 1
                 self.redis.hset(f'{self.DLGID}_ERROR','count_error_tx',count_error_tx)
                 #   
                 return False
         else:
             if self.redis.hexist(f'{self.DLGID}_ERROR','count_error_tx'):
                 self.redis.hdel(f'{self.DLGID}_ERROR','count_error_tx')   
             #
             return False
     
     
     # SI TENGO TIMER_POLL
     if self.config.lst_get('TIMER_POLL'):
         # LERO EL VALOR DE TPOLL PASADO
         timer_poll = int(self.config.lst_get('TIMER_POLL'))           
         #
         # CHEQUEO ERROR TX DURANTE UN MINUTO
         error_1min = error_1min_TX(self)
         #
         # CHEQUEO ERROR DE RTC
         RTC_error(self,error_1min)
         #
         # CHEQUEO ERRORES TX EN EL TPOLL DADO
         error_TPOLL = error_TPOLL_TX(self,timer_poll,error_1min)
         #
     else:
         # CHEQUEO ERROR TX DURANTE UN MINUTO
         error_1min = error_1min_TX(self)
         #
         # CHEQUEO ERROR DE RTC
         RTC_error(self,error_1min)
         #
         # CHEQUEO ERROR TX DURANTE 10 MINUTOS
         error_10min = error_10min_TX(self,error_1min)
         #
        
     # TRABAJO LOS LOGS
     if self.config.lst_get('TIMER_POLL'):
         if error_TPOLL:
             # MUESTRO LOG EN CONSOLA
             self.logs.print_inf(name_function, f'TX STOPPED FOR MORE THAN {timer_poll} MIN')
             #
             # ESCRIBO EN EL LOG
             self.logs.dlg_performance(f'< MAS DE {timer_poll} MIN CAIDO >')
             #
             return False
         else:
             return True
     else:    
         if error_10min:
             #
             # MUESTRO LOG EN CONSOLA
             self.logs.print_inf(name_function, 'TX STOPPED FOR MORE THAN 10 MIN')
             self.logs.print_out(name_function, 'TX_ERROR', 'SI')
             #
             # ESCRIBO EN EL LOG
             self.logs.dlg_performance(f'< MAS DE 10 MIN CAIDO > ')
             #
             # ESCRIBO EN REDIS LA ALARMA TX_ERROR CON VALOR DE ALARMA PRENDIDA
             self.redis.hset(self.DLGID,'TX_ERROR', 'SI')
             #
             return False
         else:
             #
             # ESCRIBO EN REDIS LA ALARMA TX_ERROR CON VALOR DE ALARMA APAGADA
             self.redis.hset(self.DLGID, 'TX_ERROR', 'NO')
             #
             #MUESTRO LOGS EN CONSOLA DE QUE SE ESCRIBIO LA ALARMA DE ERROR TX EN REDIS
             self.logs.print_out(name_function,'TX_ERROR', 'NO')
             #
             if error_1min:
                 # MUESTRO LOG EN CONSOLA
                 self.logs.print_inf(name_function, 'TX STOPPED')
                 #
                 # ESCRIBO EN REDIS ALARMA DE 1MIN EL EQUIPO CAIDO
                 self.redis.hset(self.DLGID, 'error_1min', 'SI')
                 #
                 # ESCRIBO EN EL LOG
                 self.logs.dlg_performance(f'< ERROR TX >')
                 #
                 return False
             else:
                 #
                 # ESCRIBO EN REDIS ALARMA DE 1MIN QUE INDICA QUE EL DATO QUE ESTA LLEGADNO ES VALIDO
                 self.redis.hset(self.DLGID, 'error_1min', 'NO')
                 #
                 return True
    def showStatesAndAlarms(self):
        '''
            funcion que lee el byte que deja el plc en el LINE y lo traduce a sus correspondientes alarmas y estados
        '''
        
        name_function = 'SHOW_STATES_&_ALARMS'

        self.logs.print_inf('MAIN',name_function)
               
        def IsValidStates(wordState):
            '''
                devuelve False se es invalida la palabra de estados recibida
            '''

            validData = True
            
            # Condiciones para que el dato de estado leidosea valido 
            ## 1- que esten prensente los 16 bits
            bitAmount = 0
            for bit in wordState:
                bitAmount += 1
            if bitAmount != 16:
                validData = False

            ## 2- que la palabra comience por 101
            bitPosition = 15
            for bitValue in wordState:
                if bitPosition == 15:
                    if bitValue != '1':
                        validData = False
                if bitPosition == 14:
                    if bitValue != '0':
                        validData = False
                if bitPosition == 13:
                    if bitValue != '1':
                        validData = False
                if bitPosition == 13:
                    break
                bitPosition -= 1 

            return validData


        decStates = int(read_param(self.DLGID_CTRL,'ST'))
        binStates = dec2bin(decStates)
                
        if IsValidStates(binStates):
            listOfAlarmsAndStates = [
                # desctription                trueValue              falseValue              bit
                'AlrLowFlow',                   'SI',                   'NO',                 #0
                'StatePump',                    'ON',                   'OFF',                #1
                'AlrLowPressure',               'SI',                   'NO',                 #2
                'AlrLowCau',                    'SI',                   'NO',                 #3
                'AlrLowFlow',                   'SI',                   'NO',                 #4
                'AlrVarFail',                   'SI',                   'NO',                 #5
                'StateVar',                     'OK',                   'FAIL',               #6
                'StateLineVar',                 'OK',                   'FAIL',               #7
            ]

            NumberOfZerosForFill = int(len(listOfAlarmsAndStates)/3) - len(binStates)

            if NumberOfZerosForFill > 0:
                # completo con ceros binStates
                while NumberOfZerosForFill > 0:
                    binStates = '0{0}'.format(binStates)
                    NumberOfZerosForFill -= 1
            
            # escribo los valores de alarmas para cada uno de los bits segun declaracion en listOfAlarmsAndStates
            bit = len(binStates)-1  
            for valueBit in binStates:
                if not bit in [15, 14, 13]:                                             # ignoro las posiciones de cabecera de control
                    if bit < int(len(listOfAlarmsAndStates)/3):                         # ignoro las posiciones que no tenga estado declarados en listOfAlarmsAndStates
                        if valueBit == '1':
                            self.redis.hset(self.DLGID_CTRL,listOfAlarmsAndStates[3*bit],listOfAlarmsAndStates[3*bit+1])
                            self.logs.print_out(name_function,listOfAlarmsAndStates[3*bit],listOfAlarmsAndStates[3*bit+1])
                        else:
                            self.redis.hset(self.DLGID_CTRL,listOfAlarmsAndStates[3*bit],listOfAlarmsAndStates[3*bit+2])
                            self.logs.print_out(name_function,listOfAlarmsAndStates[3*bit],listOfAlarmsAndStates[3*bit+2])
                bit -= 1
        else:
            self.logs.print_error(name_function,'DATOS DE ESTADOS INVALIDO: ST = {0}'.format(decStates))
    def setFrequency(self,WEB_Frequency):
        '''
            funcion que manda a setear la frecuencia de trabajo del variador
        '''
        name_function = 'MAIN'

        UFREQ = int(read_param(self.DLGID_CTRL,'UFREQ'))
                 
        # leo la variable IsfrequecyUpdating
        if not self.redis.hexist(self.DLGID_CTRL,'IsfrequecyUpdating'):
            self.redis.hset(self.DLGID_CTRL,'IsfrequecyUpdating','NO')
            IsfrequecyUpdating = self.redis.hget(self.DLGID_CTRL,'IsfrequecyUpdating')
        else:
            IsfrequecyUpdating = self.redis.hget(self.DLGID_CTRL,'IsfrequecyUpdating')

        # leo la variable lastUpdatedFrequecy
        if not self.redis.hexist(self.DLGID_CTRL,'lastUpdatedFrequecy'):
            self.redis.hset(self.DLGID_CTRL,'lastUpdatedFrequecy',0)
            lastUpdatedFrequecy = int(self.redis.hget(self.DLGID_CTRL,'lastUpdatedFrequecy'))
        else:
            lastUpdatedFrequecy = int(self.redis.hget(self.DLGID_CTRL,'lastUpdatedFrequecy'))

        # leo la variable countFrames
        if not self.redis.hexist(self.DLGID_CTRL,'countFrames'):
            self.redis.hset(self.DLGID_CTRL,'countFrames',0)
            countFrames = int(self.redis.hget(self.DLGID_CTRL,'countFrames'))
        else:
            countFrames = int(self.redis.hget(self.DLGID_CTRL,'countFrames'))
    
        if UFREQ == 100:
            if IsfrequecyUpdating == 'NO':
                if WEB_Frequency != 0:
                    self.logs.print_inf(name_function, 'SE MANDA A ACTUALIZAR LA FRECUENCIA {0}'.format(WEB_Frequency))
                    mbusWrite(self.DLGID_CTRL,'2098','interger',WEB_Frequency+100)
                    self.redis.hset(self.DLGID_CTRL,'IsfrequecyUpdating','SI')
                    self.redis.hset(self.DLGID_CTRL,'lastUpdatedFrequecy',WEB_Frequency)
                    self.redis.hset(self.DLGID_CTRL,'countFrames',0)
                else:
                    self.logs.print_inf(name_function, 'NO HAY PEDIDO DE FRECUENCIA PARA ACTUALIZAR')
            else:
                # dejo un frame de por medio para esperar un dato valido de UFREQ
                countFrames += 1
                if countFrames >= 2:
                    if lastUpdatedFrequecy == WEB_Frequency:
                        self.gda.WriteAutConf(self.DLGID_CTRL,'WEB_Frequency',0)
                        self.logs.print_inf(name_function, 'FRECUENCIA ACTUALIZADA CORRECTAMENTE')
                        self.redis.hset(self.DLGID_CTRL,'IsfrequecyUpdating','NO')
                        # 
                        # pongo en cero el registro modbus para evitar que se mande por error un valor y se comience un proceso de actualizacio de frecuencia
                        mbusWrite(self.DLGID_CTRL,'2098','interger',100)
                    else:
                        deltaFrequency = WEB_Frequency - lastUpdatedFrequecy
                        self.logs.print_inf(name_function, 'NUEVO VALOR DE ACTUALIZACION DE FRECUENCIA')
                        self.logs.print_inf(name_function, 'SE CONTINUA EL PROCESO DE VARIAR LA FRECUENCIA')
                        self.logs.print_inf(name_function, 'SE MANDA A ACTUALIZAR LA FRECUENCIA {0}'.format(deltaFrequency))
                        mbusWrite(self.DLGID_CTRL,'2098','interger',deltaFrequency)
                        self.redis.hset(self.DLGID_CTRL,'lastUpdatedFrequecy',WEB_Frequency)
                        self.redis.hset(self.DLGID_CTRL,'countFrames',0)
                else:
                    self.logs.print_inf(name_function, 'SE ESPERA UN NUEVO FRAME CON VALOR VALIDO EN UFREQ')
                    self.redis.hset(self.DLGID_CTRL,'countFrames',countFrames)
                    #
                    # pongo en cero el registro modbus para evitar que se mande por error un valor y se comience un proceso de actualizacio de frecuencia
                    mbusWrite(self.DLGID_CTRL,'2098','interger',100)
        else:
            if UFREQ >= 50 and UFREQ <= 150:
                print(UFREQ)
                self.logs.print_inf(name_function, 'ACTUALIZACION DE FRECUENCIA EN CURSO')
                self.logs.print_inf(name_function, 'SE ESPERA QUE SE TERMINE DE ACTUALIZAR LA FRECUENCIA')
                self.redis.hset(self.DLGID_CTRL,'countFrames',2)
                #
                # pongo en cero el registro modbus para evitar que se mande por error un valor y se comience un proceso de actualizacio de frecuencia
                mbusWrite(self.DLGID_CTRL,'2098','interger',100)
            else:
                self.logs.print_error(name_function, "VALOR INCORRECTO: UFREQ = {0}".format(UFREQ))
                self.logs.print_error(name_function,"SE IGNORA ESTE VALOR")
    def test_outputs(self):
        '''
        return True =>     SI EL TESTEO FUE SATISFACTORIO
        return False =>    SI HUBO ERRORES E/S
        retur None =>      SI TEST_OUTPUTS INHABILITADO
                           SI SE TRABAJA EN MODO LOCAL O HAY FALLA ELECTRICA
                           OTROS ERRORES
        '''

        name_function = 'TEST_OUTPUTS'

        # SI TEST_OUTPUTS ES False INTERRUMPO LA FUNCION
        # DEJO QUE SE TESTEEN LAS SALIDAS SI NO SE CARGA TEST_OUTPUTS
        if not (self.TEST_OUTPUTS == None):
            if not (self.TEST_OUTPUTS):
                self.logs.print_inf(name_function, 'TEST_OUTPUTS INHABILITADO')
                return None

        # LEO EL VALOR ANTERIOR DE LAS SALIDAS
        last_OUTPUTS = self.redis.hget(self.DLGID, 'last_OUTPUTS')
        #
        # CHEQUEO EL VALOR ANTERIOR DE LAS SALIDAS ES VALIDO
        if not (last_OUTPUTS):
            self.logs.print_inf(name_function,
                                f'NO EXISTE last_OUTPUTS en {self.DLGID}')
            self.logs.print_inf(name_function, 'NO SE TESTEAN SALIDAS')
            return None
        #
        # SELECCIONO EL TEST DE ACUERDO AL TIPO DE AUTOMATISMO
        if self.TYPE == 'CTRL_FREC':
            # DEFINO SALIDAS A TESTEAR
            DO_0 = get_outs(self.DLGID, last_OUTPUTS, 0)
            DO_1 = get_outs(self.DLGID, last_OUTPUTS, 1)
            #
            # DEFINO ENTRADAS A VERIFICAR
            BR1 = int(read_param(self.DLGID, 'BR1'))
            TM = int(read_param(self.DLGID, 'TM'))
            FT1 = int(read_param(self.DLGID, 'FT1'))

            # PREVEO QUE NO SE TESTEEN LAS SALIDAS BAJO MODO LOCAL O FALLA ELECTRICA
            if read_param(self.DLGID, 'LM') == '1' or read_param(
                    self.DLGID, 'FE') == '1':
                self.logs.print_in(name_function, 'LM',
                                   read_param(self.DLGID, 'LM'))
                self.logs.print_in(name_function, 'FE',
                                   read_param(self.DLGID, 'FE'))
                self.logs.print_inf(
                    name_function,
                    'NO SE TESTEAN SALIDAS POR TRABAJO EN MODO LOCAL O FALLA ELECTRICA'
                )
                return None

            # STATE: MODO DE EMERGENCIA
            if DO_0 == 0:
                if TM == 0:
                    if not (BR1 == 0 and FT1 == 0):
                        self.logs.dlg_performance(
                            f'< ERROR_E/S > [ TM = {TM} ], [ DO_1 = {DO_1}, DO_0 = {DO_0} ] <=> [ BR1 = {BR1}, FT1 = {FT1} ]'
                        )
                        self.logs.print_inf(
                            name_function,
                            f'< ERROR_E/S > [ TM = {TM} ] - [ DO_1 = {DO_1}, DO_0 = {DO_0} ] <=> [ BR1 = {BR1}, FT1 = {FT1} ]'
                        )
                        return False
                    else:
                        self.logs.print_inf(name_function, 'OUTPUTS OK')
                        return True
                elif TM == 1:
                    if not (BR1 == 1 or FT1 == 1):
                        self.logs.dlg_performance(
                            f'< ERROR_E/S > [ TM = {TM} ], [ DO_1 = {DO_1}, DO_0 = {DO_0} ] <=> [ BR1 = {BR1}, FT1 = {FT1} ]'
                        )
                        self.logs.print_inf(
                            name_function,
                            f'< ERROR_E/S > [ TM = {TM} ] - [ DO_1 = {DO_1}, DO_0 = {DO_0} ] <=> [ BR1 = {BR1}, FT1 = {FT1} ]'
                        )
                        return False
                    else:
                        self.logs.print_inf(name_function, 'OUTPUTS OK')
                        return True
                else:
                    self.logs.print_inf(
                        name_function,
                        f'VALOR NO RECONOCIDO EN TM [ TM = {TM} ]')
                    self.logs.script_performance(
                        f'VALOR NO RECONOCIDO EN TM [ TM = {TM} ]')
                    return None

            elif DO_0 == 1:
                if DO_1 == 0:
                    if not (BR1 == 0 and FT1 == 0):
                        self.logs.dlg_performance(
                            f'< ERROR_E/S > [ DO_1 = {DO_1}, DO_0 = {DO_0} ] <=> [ BR1 = {BR1}, FT1 = {FT1} ]'
                        )
                        self.logs.print_inf(
                            name_function,
                            f'< ERROR_E/S > [ DO_1 = {DO_1}, DO_0 = {DO_0} ] <=> [ BR1 = {BR1}, FT1 = {FT1} ]'
                        )
                        return False
                    else:
                        self.logs.print_inf(name_function, 'OUTPUTS OK')
                        return True
                elif DO_1 == 1:
                    if not (BR1 == 1 or FT1 == 1):
                        self.logs.dlg_performance(
                            f'< ERROR_E/S > [ DO_1 = {DO_1}, DO_0 = {DO_0} ] <=> [ BR1 = {BR1}, FT1 = {FT1} ]'
                        )
                        self.logs.print_inf(
                            name_function,
                            f'< ERROR_E/S > [ DO_1 = {DO_1}, DO_0 = {DO_0} ] <=> [ BR1 = {BR1}, FT1 = {FT1} ]'
                        )
                        return False
                    else:
                        self.logs.print_inf(name_function, 'OUTPUTS OK')
                        return True
                else:
                    self.logs.print_inf(
                        name_function,
                        f'VALOR NO RECONOCIDO EN DO_1 [ DO_1 = {DO_1} ]')
                    self.logs.script_performance(
                        f'VALOR NO RECONOCIDO EN DO_1 [ DO_1 = {DO_1} ]')
                    return None
            # MODO DE CONTROL
            else:
                self.logs.print_inf(
                    name_function,
                    f'VALOR NO RECONOCIDO EN D0_0 [ DO_0 = {DO_0} ]')
                self.logs.script_performance(
                    f'VALOR NO RECONOCIDO EN D0_0 [ DO_0 = {DO_0} ]')
                return None
    def event_detection(self):

        name_function = 'EVENT_DETECTION'

        # SI EVENT_DETECTION ES False INTERRUMPO LA FUNCION
        if not (self.EVENT_DETECTION == None):
            if not (self.EVENT_DETECTION):
                self.logs.print_inf(name_function,
                                    'EVENT_DETECTION INHABILITADO')
                return

        # PIERTA DEL GABINETE
        if read_param(self.DLGID, 'GA') == '1':
            self.logs.print_inf(name_function, 'GABINETE_ABIERTO')
            #
            # ESCRIBO EN EL LOG
            self.logs.dlg_performance(f'< {name_function} > GABINETE_ABIERTO')

        # FALLA ELECTRICA
        if read_param(self.DLGID, 'FE') == '1':
            self.logs.print_inf(name_function, 'FALLA_ELECTRICA')
            #
            # ESCRIBO EN EL LOG
            self.logs.dlg_performance(f'< {name_function} > FALLA_ELECTRICA')

        # FALLA TERMICA 1
        if read_param(self.DLGID, 'FT1') == '1':
            self.logs.print_inf(name_function, 'FALLA_TERMICA_1')
            #
            # ESCRIBO EN EL LOG
            self.logs.dlg_performance(f'< {name_function} > FALLA_TERMICA_1')

        # TRABAJO EN MODO LOCAL
        if read_param(self.DLGID, 'LM') == '1':
            self.logs.print_inf(name_function, 'MODO_LOCAL')
            #
            # ESCRIBO EN EL LOG
            self.logs.dlg_performance(f'< {name_function} > MODO_LOCAL')

        # TRABAJO EN MODO REMOTO
        if self.redis.hget(self.DLGID,
                           dic.get_dic('WEB_MODE', 'name')) == dic.get_dic(
                               'WEB_MODE', 'False_value'):
            #
            # CHEQUEO QUE SE ESTE MANDANDO A PRENDER LA BOMBA
            if self.redis.hget(self.DLGID,
                               dic.get_dic('PUMP_1_WEB_MODE',
                                           'name')) == dic.get_dic(
                                               'PUMP_1_WEB_MODE',
                                               'True_value'):
                #
                # ESCRIBO EN EL LOG
                PUMP_FREC = self.redis.hget(self.DLGID,
                                            dic.get_dic('PUMP_FREC', 'name'))
                self.logs.print_inf(
                    name_function,
                    f'MODO REMOTO => PRENDER BOMBA [ PUMP_FREC = {PUMP_FREC} ]'
                )
                self.logs.dlg_performance(
                    f'< {name_function} > MODO REMOTO => PRENDER BOMBA [ PUMP_FREC = {PUMP_FREC} ]'
                )
                #
            elif self.redis.hget(self.DLGID,
                                 dic.get_dic('PUMP_1_WEB_MODE',
                                             'name')) == dic.get_dic(
                                                 'PUMP_1_WEB_MODE',
                                                 'False_value'):
                # ESCRIBO EN EL LOG
                self.logs.print_inf(name_function,
                                    f'MODO REMOTO => APAGAR BOMBA')
                self.logs.dlg_performance(
                    f'< {name_function} > MODO REMOTO => APAGAR BOMBA')

        # TRABAJO EN MODO EMERGENCIA
        if self.redis.hget(
                self.DLGID, dic.get_dic('WEB_MODE', 'name')) == dic.get_dic(
                    'WEB_MODE', 'value_1') or self.redis.hget(
                        self.DLGID, dic.get_dic('WEB_MODE',
                                                'name')) == dic.get_dic(
                                                    'WEB_MODE', 'value_2'):
            #
            # ESCRIBO EN EL LOG
            self.logs.print_inf(name_function, f'MODO BOYA O TIMER')
            self.logs.dlg_performance(f'< {name_function} > MODO BOYA O TIMER')

        # TRABAJO CON EL SISTEMA DE REFERENCIA_1
        if self.redis.hget(self.DLGID, 'flag_work_syst_ref_1') == 'SI':
            #
            FREC = self.redis.hget(self.DLGID, 'FREC')
            #
            # ESCRIBO EN EL LOG
            self.logs.print_inf(
                name_function,
                f'TRABAJO CON LA REFERENCIA_1 [ FREC = {FREC} ]')
            self.logs.dlg_performance(
                f'< {name_function} > TRABAJO CON LA REFERENCIA_1 [ FREC = {FREC} ]'
            )

        # TRABAJO CON FRECUENCIA MAXIMA
        if int(self.redis.hget(self.DLGID, 'FREC')) == 7:
            self.logs.dlg_performance(
                f'< {name_function} > SE ALCANZA FRECUENCIA MAXIMA')
    def chequeo_alarmas(self):

        name_function = 'CHEQUEO_ALARMAS'

        # PIERTA DEL GABINETE
        if read_param(self.DLGID_CTRL, 'GA') == '1':
            self.logs.print_inf(name_function, 'GABINETE_ABIERTO')
            # ESCRIBO LA ALARMA EN REDIS
            self.redis.hset(self.DLGID_CTRL,
                            dic.get_dic('GABINETE_ABIERTO', 'name'),
                            dic.get_dic('TX_ERROR', 'True_value'))
        elif read_param(self.DLGID_CTRL, 'GA') == '0':
            # ESCRIBO LA ALARMA EN REDIS
            self.redis.hset(self.DLGID_CTRL,
                            dic.get_dic('GABINETE_ABIERTO', 'name'),
                            dic.get_dic('TX_ERROR', 'False_value'))
        else:
            self.logs.print_inf(
                name_function,
                f"error in {name_function}, GA = {read_param(self.DLGID_CTRL,'GA')}"
            )
            # DEJAR REGISTRO DEL ERROR
            self.logs.script_performance(
                f"error in {name_function}, GA = {read_param(self.DLGID_CTRL,'GA')}"
            )

        # FALLA ELECTRICA
        if read_param(self.DLGID_CTRL, 'FE') == '1':
            self.logs.print_inf(name_function, 'FALLA ELECTRICA')
            # ESCRIBO LA ALARMA EN REDIS
            self.redis.hset(self.DLGID_CTRL,
                            dic.get_dic('FALLA_ELECTRICA', 'name'),
                            dic.get_dic('FALLA_ELECTRICA', 'True_value'))
        elif read_param(self.DLGID_CTRL, 'FE') == '0':
            # ESCRIBO LA ALARMA EN REDIS
            self.redis.hset(self.DLGID_CTRL,
                            dic.get_dic('FALLA_ELECTRICA', 'name'),
                            dic.get_dic('FALLA_ELECTRICA', 'False_value'))
        else:
            self.logs.print_inf(
                name_function,
                f"error in {name_function}, FE = {read_param(self.DLGID_CTRL,'FE')}"
            )
            # DEJAR REGISTRO DEL ERROR
            self.logs.script_performance(
                f"error in {name_function}, FE = {read_param(self.DLGID_CTRL,'FE')}"
            )

        # FALLA TERMICA 1
        if read_param(self.DLGID_CTRL, 'FT1') == '1':
            self.logs.print_inf(name_function, 'FALLA TERMICA 1')
            # ESCRIBO LA ALARMA EN REDIS
            self.redis.hset(self.DLGID_CTRL,
                            dic.get_dic('FALLA_TERMICA_1', 'name'),
                            dic.get_dic('FALLA_ELECTRICA', 'True_value'))
        elif read_param(self.DLGID_CTRL, 'FT1') == '0':
            # ESCRIBO LA ALARMA EN REDIS
            self.redis.hset(self.DLGID_CTRL,
                            dic.get_dic('FALLA_TERMICA_1', 'name'),
                            dic.get_dic('FALLA_ELECTRICA', 'False_value'))
        else:
            self.logs.print_inf(
                name_function,
                f"error in {name_function}, FT1 = {read_param(self.DLGID_CTRL,'FT1')}"
            )
            # DEJAR REGISTRO DEL ERROR
            self.logs.script_performance(
                f"error in {name_function}, FT1 = {read_param(self.DLGID_CTRL,'FT1')}"
            )
 def pump_time(self, channel_pump_name, no_pump):
     #
     name_function = f'PUMP{no_pump}_TIME'
     #
     from datetime import datetime, date, time, timedelta
     #
     pump_state = int(read_param(self.DLGID_CTRL, channel_pump_name))
     #
     # PREPARO VARIABLES DE TIEMPO
     #
     ## TIEMPO TOTAL
     if not (self.redis.hexist(self.DLGID_CTRL,
                               f'pump{no_pump}_total_time')):
         self.redis.hset(self.DLGID_CTRL, f'pump{no_pump}_total_time',
                         '2020,1,1,0,0,0,0')
         pump_total_time = datetime(2020, 1, 1, 0, 0, 0, 0)
         #
         # ESCRIBO LA VARIABLE DE VISUALIZACION
         self.redis.hset(self.DLGID_CTRL,
                         dic.get_dic(f'PUMP{no_pump}_TOTAL_TIME', 'name'),
                         '0 horas')
     else:
         # OBTENGO pump_total_time EN FORMATO datetime
         str_pump_total_time = self.redis.hget(self.DLGID_CTRL,
                                               f'pump{no_pump}_total_time')
         lst_pump_total_time = str_pump_total_time.split(',')
         pump_total_time = datetime(int(lst_pump_total_time[0]),
                                    int(lst_pump_total_time[1]),
                                    int(lst_pump_total_time[2]),
                                    int(lst_pump_total_time[3]),
                                    int(lst_pump_total_time[4]),
                                    int(lst_pump_total_time[5]),
                                    int(lst_pump_total_time[6]))
         #
         # INCREMENTO 1 MINUTO EN pump_total_time SI LA BOMBA ESTA PRENDIDA
         if pump_state == 1:
             # SUMO UN MINUTO AL CONTEO DE TIEMPO
             pump_total_time = pump_total_time + timedelta(minutes=1)
             #
             # VEO LA DIFERENCIA DE TIEMPO RESPECTO A LA REFERENCIA INICIAL
             delta_total_time = pump_total_time - datetime(
                 2020, 1, 1, 0, 0, 0, 0)
             #
             # CONVIERTO LA DIFERENCIA A HORAS
             delta_total_time_hours = int(delta_total_time.days * 24 +
                                          delta_total_time.seconds / 3600)
             #
             # ESCRIBO LA VARIABLE DE VISUALIZACION
             self.redis.hset(
                 self.DLGID_CTRL,
                 dic.get_dic(f'PUMP{no_pump}_TOTAL_TIME', 'name'),
                 f'{delta_total_time_hours} horas')
             #
             self.logs.print_out(
                 name_function,
                 dic.get_dic(f'PUMP{no_pump}_TOTAL_TIME', 'name'),
                 f'{delta_total_time_hours} horas')
         #
         # GUARDO pump_total_time EN REDIS
         str_pump_total_time = f'{pump_total_time.year},{pump_total_time.month},{pump_total_time.day},{pump_total_time.hour},{pump_total_time.minute},{pump_total_time.second},{pump_total_time.microsecond}'
         self.redis.hset(self.DLGID_CTRL, f'pump{no_pump}_total_time',
                         str_pump_total_time)
    def control_sistema(self, dlgid_ref, channel_ref, MAG_REF):

        name_function = 'CONTROL_SISTEMA'

        WND = 0.1  # VENTANA DE FRECUENCIA ABIERTA

        # SI NO EXISTE LMIN LO CREO CON VALOR 1
        if not (self.redis.hexist(self.DLGID_CTRL,
                                  dic.get_dic('MAG_REF', 'name'))):
            self.redis.hset(self.DLGID_CTRL, dic.get_dic('MAG_REF', 'name'),
                            dic.get_dic('MAG_REF', 'True_value'))

        #
        #ESTABLEZCO LMIN Y LMAX A PARTIR DE WND
        LMIN = MAG_REF - WND
        LMAX = MAG_REF + WND
        #
        # LEO EL CANAL DE REFERENCIA
        if self.redis.hexist(dlgid_ref, 'LINE'):
            REF = float(read_param(dlgid_ref, channel_ref))
        else:
            self.logs.print_inf(
                name_function,
                f"error in {name_function}, {self.CHANNEL_REF} = {read_param(self.DLGID_CTRL,self.CHANNEL_REF)}"
            )

        # MUESTRO LOGS
        self.logs.print_in(name_function, 'ENABLE_OUTPUTS',
                           self.ENABLE_OUTPUTS)
        self.logs.print_in(name_function, 'TYPE_IN_FREC', self.TYPE_IN_FREC)
        self.logs.print_in(name_function, 'MAG_REF', MAG_REF)
        self.logs.print_in(name_function, 'WND', WND)
        self.logs.print_in(name_function, 'REF', REF)

        # SI NO FREC LMIN LO CREO CON VALOR 0
        if not (self.redis.hexist(self.DLGID_CTRL, 'FREC')):
            self.redis.hset(self.DLGID_CTRL, 'FREC', 0)
        # LEO EL VALOR DE LA FRECUENCIA ACTUAL
        FREC = int(self.redis.hget(self.DLGID_CTRL, 'FREC'))
        self.logs.print_in(name_function, 'LAST_FREC', FREC)

        if REF < LMIN:
            self.logs.print_inf(name_function, 'PRESION BAJA')
            if FREC < 7:
                FREC += 1
                self.logs.print_inf(name_function, 'SE AUMENTA LA FRECUENCIA')
                #
            else:
                self.logs.print_inf(name_function,
                                    'SE ALCANZA FRECUENCIA MAXIMA')
                #self.logs.dlg_performance(f'< {name_function} > SE ALCANZA FRECUENCIA MAXIMA')

        elif REF > LMAX:
            self.logs.print_inf(name_function, 'PRESION ALTA')
            if FREC > 0:
                FREC -= 1
                self.logs.print_inf(name_function,
                                    'SE DISMINUYE LA FRECUENCIA')
        else:
            self.logs.print_inf(name_function,
                                'PRESION DENTRO DEL RANGO SELECCIONADO')

        # MANDO A PRENDER LA BOMBA
        pump1(self.DLGID_CTRL, True)

        # CHEQUEO SI LAS SALIDAS TIENEN QUE ACOPLARSE A ENTRADAS NPN o PNP Y MANDO A SETEAR EN CASO DE ENABLE_OUTPUTS
        if self.ENABLE_OUTPUTS:
            if self.TYPE_IN_FREC == 'NPN':
                douts(self.DLGID_CTRL, not_dec(FREC, 3))
            elif self.TYPE_IN_FREC == 'PNP':
                douts(self.DLGID_CTRL, FREC)
            else:
                self.logs.print_inf(
                    name_function,
                    f"error in {name_function}, TYPE_IN_FREC = {self.TYPE_IN_FREC}"
                )
                self.logs.script_performance(
                    f"error in {name_function}, TYPE_IN_FREC = {self.TYPE_IN_FREC}"
                )
        else:
            self.logs.print_inf(
                name_function,
                f"SALIDAS DESCACTIVADAS [ENABLE_OUTPUTS = {self.ENABLE_OUTPUTS}]"
            )
            self.logs.script_performance(
                f"{name_function} ==> SALIDAS DESCACTIVADAS [ENABLE_OUTPUTS = {self.ENABLE_OUTPUTS}]"
            )

        # GUARODO LA FRECUENCIA ACTUAL DE TRABAJO
        self.logs.print_out(name_function, 'CURR_FREC', FREC)
        self.redis.hset(self.DLGID_CTRL, 'FREC', FREC)