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()
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()
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()
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
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))
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.")
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()
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))
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()
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()
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." )