예제 #1
0
    def run(self):
        self.__monitor()
        self.running = True
        while self.running:
            try:
                result = self.conn.recv()
                if isinstance(result, UnknownPlcTagException):
                    raise UnknownPlcTagException(result)
                elif isinstance(result, TerminateMessage):
                    self.running = False
                    logger.info("Terminating monitoring of '{}'.".format(
                        self.motor.name))
                elif isinstance(result, MonitorResponseMessage):
                    motor_var_idx = self.motor.plc_vars_map[result.name]
                    var = self.motor.vars[motor_var_idx]['value']
                    if type(var) is int:
                        self.motor.vars[motor_var_idx]['value'] = int(
                            result.value)
                    elif type(var) is bool:
                        self.motor.vars[motor_var_idx]['value'] = result.value
                    else:
                        raise RuntimeError('Unsupported type \'{}\'.'.format(
                            type(var)))
                else:
                    logger.error("Received unexpected message type '%s'.",
                                 type(result))
            except EOFError:
                logger.exception("Received EOF.")
                self.running = False
            except UnknownPlcTagException:
                logger.exception("Unknown PLC Tag.")

        self.__close()
예제 #2
0
    def run(self):
        self.__monitor()
        while not self.dev.shutdown_event.is_set():
            try:
                if self.conn.poll():
                    result = self.conn.recv()
                    if isinstance(result, UnknownPlcTagException):
                        raise UnknownPlcTagException(result)
                    elif isinstance(result, TerminateMessage):
                        logger.info("Terminating monitoring of '{}'.".format(
                            self.dev.name))
                        break
                    elif isinstance(result, MonitorResponseMessage):
                        dev_var_idx = self.dev.plc_vars_map[result.name]
                        var = self.dev.vars[dev_var_idx]['value']
                        if type(var) is int:
                            self.dev.vars[dev_var_idx]['value'] = int(
                                result.value)
                        elif type(var) is bool:
                            self.dev.vars[dev_var_idx]['value'] = result.value
                        else:
                            raise RuntimeError(
                                'Unsupported type \'{}\'.'.format(type(var)))
                    else:
                        logger.error("Received unexpected message type '%s'.",
                                     type(result))
            except EOFError:
                logger.exception("Received EOF.")
                break
            except UnknownPlcTagException:
                logger.exception("Unknown PLC Tag.")

        self.__close()
예제 #3
0
    def run(self):
        self.__create_connection()
        tag_names = [self.rule['var_name']]
        self.conn.send(MonitorMessage(tag_names))
        while True:
            try:
                if self.conn.poll():
                    result = self.conn.recv()
                    if isinstance(result, UnknownPlcTagException):
                        raise UnknownPlcTagException(result)
                    elif isinstance(result, TerminateMessage):
                        logger.info("Terminating monitoring of '{}'.".format(
                            self.rule['var_name']))
                        break
                    elif isinstance(result, MonitorResponseMessage):
                        if self.rule['predicate'] == Predicates.MAXVAL:
                            if int(result.value) > self.rule['value']:
                                logger.warning(
                                    "ALERT! '{}' tag [{}={}] exceeds max value of {}."
                                    .format(self.rule['plc'].name,
                                            self.rule['var_name'],
                                            result.value, self.rule['value']))
                    else:
                        logger.error("Received unexpected message type '%s'.",
                                     type(result))
            except EOFError:
                logger.exception("Received EOF.")
                break
            except UnknownPlcTagException:
                logger.exception("Unknown PLC Tag.")

        self.conn.close()
예제 #4
0
 def __send_message(self, msg):
     self.__send(msg)
     result = self.conn.recv()
     self.__close()
     if isinstance(result, UnknownPlcTagException):
         raise UnknownPlcTagException(result)
     elif isinstance(result, NotSupportedPlcTagTypeException):
         raise NotSupportedPlcTagTypeException(result)
     elif isinstance(result, NotSupportedPlcTagClassException):
         raise NotSupportedPlcTagClassException(result)
     else:
         return result
예제 #5
0
    def set_var_value(self, name, value):
        for d in self.vars:
            # Check if variable exists in PLC code
            if d['name'] == name:
                new_value = None
                old_value = self.get_var_value(name)
                val_to_sync = None
                types = PlcTypes()
                clazz = d['class']
                plc_clazzes = PlcClasses()
                var_type = d['type']
                # Prepare args for lib call
                idx = self.vars.index(d)
                c_idx = c_int(idx)
                if var_type == types.INT or var_type == types.DINT or var_type == types.SINT:
                    val_to_sync = int(value)
                    new_value = c_int(val_to_sync)
                elif var_type == types.BOOL:
                    # Value sent via Modbus may be 0/1
                    val_to_sync = value.lower() == "true" or value == "1"
                    new_value = c_bool(val_to_sync)

                if new_value is None:
                    raise NotSupportedPlcTagTypeException(
                        "Type: '{}' is currently not supported.".format(
                            var_type))

                if clazz == plc_clazzes.IN or clazz == plc_clazzes.OUT or clazz == plc_clazzes.MEM:
                    # TODO: Error handling
                    res = self.__set_int_val_by_idx_p(c_idx, byref(new_value))
                elif clazz == plc_clazzes.VAR:
                    # TODO: Error handling
                    res = self.__set_int_val_by_idx_t(c_idx, byref(new_value))
                else:
                    raise NotSupportedPlcTagClassException(
                        "Class '{}' currently not supported.\n".format(clazz))
                if res != 0:
                    raise RuntimeError(
                        "Error! Lib call 'set_val_by_idx' returned error.")
                else:
                    logger.info(
                        "'{}' value changed {} -> {} in device '{}'.".format(
                            name, old_value, val_to_sync, self.name))
                    self.__sync_mb_blocks(idx, val_to_sync)
                    self.__notify_watcher(idx, val_to_sync)
                    return

        raise UnknownPlcTagException(
            "Variable name '{}' does not exist in PLC.\n".format(name))
예제 #6
0
 def __send_message(self, msg):
     self.__send(msg)
     try:
         result = self.conn.recv()
         self.__close()
         if isinstance(result, UnknownPlcTagException):
             raise UnknownPlcTagException(result)
         else:
             return result
     except UnknownPlcTagException:
         if isinstance(msg, GetTagMessage) or isinstance(
                 msg, SetTagMessage):
             return "ERROR: Variable name '{}' does not exist in PLC.\n".format(
                 msg.name)
         else:
             logger.exception("Unknown PLC Tag.")
예제 #7
0
    def run(self):
        self.__create_connection()
        tag_names = [self.rule['plc_var']]
        self.conn.send(MonitorMessage(tag_names))
        while True:
            try:
                result = self.conn.recv()
                if isinstance(result, UnknownPlcTagException):
                    raise UnknownPlcTagException(result)
                elif isinstance(result, TerminateMessage):
                    logger.info("Terminating monitoring of '{}'.".format(
                        self.rule['plc_var']))
                    break
                elif isinstance(result, MonitorResponseMessage):
                    if self.rule['predicate'] == Predicates.EQUALS:
                        for var in self.rule['hmi'].vars:
                            warn = False
                            if var['name'] == self.rule['hmi_var']:
                                if type(var['value']) is int:
                                    if var['value'] != int(result.value):
                                        warn = True
                                elif type(var['value']) is bool:
                                    if var['value'] != (result.value
                                                        == 'True'):
                                        warn = True
                                if warn:
                                    logger.warning(
                                        "ALERT! '{}' tag [{}={}] does not equal '{}' tag [{}={}]."
                                        .format(self.rule['hmi'].name,
                                                var['name'], var['value'],
                                                self.rule['plc'].name,
                                                self.rule['plc_var'],
                                                result.value))
                else:
                    logger.error("Received unexpected message type '%s'.",
                                 type(result))
            except EOFError:
                logger.exception("Received EOF.")
                break
            except UnknownPlcTagException:
                logger.exception("Unknown PLC Tag.")

        self.conn.close()
예제 #8
0
    def get_var_value(self, name):
        for d in self.vars:
            # Check if variable exists in PLC code
            if d['name'] == name:
                # Prepare args for lib call
                idx = c_int(self.vars.index(d))
                clazz = d['class']
                plc_clazzes = PlcClasses()
                if clazz == plc_clazzes.IN or clazz == plc_clazzes.OUT or clazz == plc_clazzes.MEM:
                    ptr = POINTER(c_void_p)()
                    res = self.__get_ref_by_idx_p(idx, byref(ptr))
                elif clazz == plc_clazzes.VAR:
                    ptr = c_void_p()
                    res = self.__get_ref_by_idx_t(idx, byref(ptr))
                else:
                    raise NotSupportedPlcTagClassException(
                        "Class '{}' currently not supported.\n".format(clazz))
                if res == 0:
                    var_type = None
                    types = PlcTypes()
                    if d['type'] == types.INT or d['type'] == types.DINT or d[
                            'type'] == types.SINT:
                        var_type = POINTER(c_int)
                    elif d['type'] == types.BOOL:
                        var_type = POINTER(c_bool)
                    if var_type is None:
                        raise NotSupportedPlcTagTypeException(
                            "Type: '{}' is currently not supported.".format(
                                d['type']))
                    var_res = cast(self.__get_ptr_accessor(clazz, ptr),
                                   var_type)
                    return var_res[0]
                else:
                    raise RuntimeError(
                        "Error! Lib call 'get_ref_by_idx' returned error.")

        raise UnknownPlcTagException(
            "Variable name '{}' does not exist in PLC.\n".format(name))
예제 #9
0
    def run(self):
        self.__create_connection()
        # TODO: FIX UPPER
        self.conn.send(GetTagMessage(self.rule['plc_var'].upper()))
        try:
            result = self.conn.recv()
            if isinstance(result, UnknownPlcTagException):
                raise UnknownPlcTagException(result)
            elif isinstance(result, GetTagResponseMessage):
                if self.rule['predicate'] == Predicates.EQUALS:
                    for var in self.rule['hmi'].vars:
                        warn = False
                        if var['name'] == self.rule['hmi_var']:
                            if type(var['value']) is int:
                                if var['value'] != int(result.value):
                                    warn = True
                            elif type(var['value']) is bool:
                                if var['value'] != (result.value == 'True'):
                                    warn = True
                            if warn:
                                logger.warning(
                                    "ALERT! '{}' tag [{}={}] does not equal '{}' tag [{}={}]."
                                    .format(self.rule['hmi'].name, var['name'],
                                            var['value'],
                                            self.rule['plc'].name,
                                            self.rule['plc_var'],
                                            result.value))
            else:
                logger.error("Received unexpected message type '%s'.",
                             type(result))
        except EOFError:
            logger.exception("Received EOF.")
        except UnknownPlcTagException:
            logger.exception("Unknown PLC Tag.")

        self.conn.close()
예제 #10
0
        def run(self):
            self.__create_connection()
            tag_names = []
            # If motor is none, all PLC tags should be monitored
            if self.motor is None:
                self.conn.send(GetAllTagNamesMessage())
            else:
                tag_names = self.motor.plc_vars_map.keys()
                self.conn.send(MonitorMessage(tag_names))
            while True:
                try:
                    result = self.conn.recv()
                    if isinstance(result, UnknownPlcTagException):
                        raise UnknownPlcTagException(result)
                    elif isinstance(result, TerminateMessage):
                        logger.info("Terminating monitoring of '{}'.".format(
                            ', '.join(tag_names)))
                        break
                    elif isinstance(result, GetAllTagNamesResponseMessage):
                        tag_names = result.tag_names
                        # Recreate connection before sending new message
                        self.listener_ready = False
                        self.__create_connection()
                        self.conn.send(MonitorMessage(tag_names))
                    elif isinstance(result, MonitorResponseMessage):
                        dev_name = None
                        # First check if we are currently monitoring a PLC or motor
                        if self.motor is None:
                            # We are monitoring a PLC
                            if self.plc_name in device_to_client_map:
                                dev_name = self.plc_name
                        else:
                            if self.motor.name in device_to_client_map:
                                dev_name = self.motor.name
                                # We have to alter the name of the result set, as we are receiving PLC tag
                                # changes, yet we have to transmit the motor tag
                                # The 'plc_vars_map' will contain the mapping: {PLC_TAG_NAME: IDX_MOTOR_VARS}
                                idx_motor_var = self.motor.plc_vars_map.get(
                                    result.name)
                                if idx_motor_var is not None:
                                    # Set the correct motor tag name
                                    result.name = self.motor.vars[
                                        idx_motor_var]['name']
                                else:
                                    logger.error(
                                        "Received unknown PLC tag (motor tag map)."
                                    )

                        if dev_name is not None:
                            # logger.info("'%s' variable changed [%s=%s].", dev_name, result.name, result.value)
                            for client in device_to_client_map[dev_name]:
                                client.sendMessage(u"" + json.dumps({
                                    'tag_change': {
                                        'name': result.name,
                                        'value': result.value
                                    }
                                }))
                    else:
                        logger.error("Received unexpected message type '%s'.",
                                     type(result))
                except EOFError:
                    logger.exception("Received EOF.")
                    break
                except UnknownPlcTagException:
                    logger.exception("Unknown PLC Tag.")

            self.conn.close()
예제 #11
0
    def run(self):
        self.__create_connection()
        tag_names = []
        # If motor is none, all PLC tags should be monitored
        if self.motor is None:
            self.conn.send(GetAllTagNamesMessage())
        else:
            tag_names = self.motor.plc_vars_map.keys()
            self.conn.send(MonitorMessage(tag_names))
        while not self.stop_event.is_set():
            try:
                if self.conn.poll():
                    result = self.conn.recv()
                    if isinstance(result, UnknownPlcTagException):
                        raise UnknownPlcTagException(result)
                    elif isinstance(result, TerminateMessage):
                        logger.info("Terminating monitoring of '{}'.".format(
                            ', '.join(tag_names)))
                        break
                    elif isinstance(result, GetAllTagNamesResponseMessage):
                        tag_names = result.tag_names
                        # Recreate connection before sending new message
                        self.listener_ready = False
                        self.__create_connection()
                        self.conn.send(MonitorMessage(tag_names))
                    elif isinstance(result, MonitorResponseMessage):
                        # First check if we are currently monitoring a PLC or motor
                        if self.motor is None:
                            dev_name = self.plc_name
                        else:
                            dev_name = self.motor.name
                            # We have to alter the name of the result set, as we are receiving PLC tag
                            # changes, yet we have to transmit the motor tag
                            # The 'plc_vars_map' will contain the mapping: {PLC_TAG_NAME: IDX_MOTOR_VARS}
                            idx_motor_var = self.motor.plc_vars_map.get(
                                result.name)
                            if idx_motor_var is not None:
                                # Set the correct motor tag name
                                result.name = self.motor.vars[idx_motor_var][
                                    'name']
                            else:
                                logger.error(
                                    "Received unknown PLC tag (motor tag map)."
                                )
                        if dev_name is not None:
                            state_logger.info(
                                "[%s] '%s' variable changed [%s=%s].",
                                result.timestamp.strftime(
                                    '%Y-%m-%d %H:%M:%S.%f')[:-3], dev_name,
                                result.name, result.value)
                    else:
                        logger.error("Received unexpected message type '%s'.",
                                     type(result))
            except EOFError:
                logger.exception("Received EOF.")
                break
            except UnknownPlcTagException:
                logger.exception("Unknown PLC Tag.")

        try:
            # Announce to PLC supervisor that we stop monitoring PLC tags
            logger.info("Announcing PLC supervisor to stop monitoring.")
            self.conn.send(StopMonitoringMessage())
        except IOError, e:
            if e.errno == errno.EPIPE:
                pass
            else:
                logger.exception(
                    "Could not announce to PLC supervisor to stop monitoring states for state logging."
                )