def convert(self, config, data): self.__result["telemetry"] = [] self.__result["attributes"] = [] for config_data in data: if self.__result.get(config_data) is None: self.__result[config_data] = [] for tag in data[config_data]: log.debug(tag) data_sent = data[config_data][tag]["data_sent"] input_data = data[config_data][tag]["input_data"] log.debug("Called convert function from %s with args", self.__class__.__name__) log.debug(data_sent) log.debug(input_data) result = None if data_sent.get("functionCode") == 1 or data_sent.get( "functionCode") == 2: result = input_data.bits log.debug(result) if "registerCount" in data_sent: result = result[:data_sent["registerCount"]] else: result = result[0] elif data_sent.get("functionCode") == 3 or data_sent.get( "functionCode") == 4: result = input_data.registers byte_order = data_sent.get("byteOrder", "LITTLE") reg_count = data_sent.get("registerCount", 1) type_of_data = data_sent["type"] try: if byte_order == "LITTLE": decoder = BinaryPayloadDecoder.fromRegisters( result, byteorder=Endian.Little) elif byte_order == "BIG": decoder = BinaryPayloadDecoder.fromRegisters( result, byteorder=Endian.Big) else: log.warning("byte order is not BIG or LITTLE") continue except Exception as e: log.error(e) if type_of_data == "string": result = decoder.decode_string(2 * reg_count) elif type_of_data == "long": if reg_count == 1: result = decoder.decode_16bit_int() elif reg_count == 2: result = decoder.decode_32bit_int() elif reg_count == 4: result = decoder.decode_64bit_int() else: log.warning( "unsupported register count for long data type in response for tag %s", data_sent["tag"]) continue elif type_of_data == "double": if reg_count == 2: result = decoder.decode_32bit_float() elif reg_count == 4: result = decoder.decode_64bit_float() else: log.warning( "unsupported register count for double data type in response for tag %s", data_sent["tag"]) continue elif type_of_data == "bit": if "bit" in data_sent: if type(result) == list: if len(result) > 1: log.warning( "with bit parameter only one register is expected, got more then one in response for tag %s", data_sent["tag"]) continue result = result[0] position = 15 - data_sent["bit"] # reverse order # transform result to string representation of a bit sequence, add "0" to make it longer >16 result = "0000000000000000" + str(bin(result)[2:]) # get length of 16, then get bit, then cast it to int(0||1 from "0"||"1", then cast to boolean) result = bool( int((result[len(result) - 16:])[15 - position])) else: log.error( "Bit address not found in config for modbus connector for tag: %s", data_sent["tag"]) else: log.warning( "unknown data type, not string, long or double in response for tag %s", data_sent["tag"]) continue try: self.__result[config_data].append({tag: int(result)}) except ValueError: self.__result[config_data].append({tag: int(result, 16)}) self.__result["telemetry"] = self.__result.pop("timeseries") log.debug(self.__result) return self.__result
def convert(self, config, data): byte_order_str = config.get("byteOrder", "LITTLE") byte_order = Endian.Big if byte_order_str.upper( ) == "BIG" else Endian.Little builder = BinaryPayloadBuilder(byteorder=byte_order) builder_functions = { "string": builder.add_string, "bits": builder.add_bits, "8int": builder.add_8bit_int, "16int": builder.add_16bit_int, "32int": builder.add_32bit_int, "64int": builder.add_64bit_int, "8uint": builder.add_8bit_uint, "16uint": builder.add_16bit_uint, "32uint": builder.add_32bit_uint, "64uint": builder.add_64bit_uint, "16float": builder.add_16bit_float, "32float": builder.add_32bit_float, "64float": builder.add_64bit_float } value = None if data.get("data") and data["data"].get("params") is not None: value = data["data"]["params"] else: value = config["value"] lower_type = config.get("type", config.get("tag", "error")).lower() if lower_type == "error": log.error('"type" and "tag" - not found in configuration.') variable_size = config.get("registerCount", 1) * 8 if lower_type in ["integer", "dword", "dword/integer", "word", "int"]: lower_type = str(variable_size) + "int" assert builder_functions.get(lower_type) is not None builder_functions[lower_type](value) elif lower_type in [ "uint", "unsigned", "unsigned integer", "unsigned int" ]: lower_type = str(variable_size) + "uint" assert builder_functions.get(lower_type) is not None builder_functions[lower_type](value) elif lower_type in ["float", "double"]: lower_type = str(variable_size) + "float" assert builder_functions.get(lower_type) is not None builder_functions[lower_type](value) elif lower_type in ["coil", "bits"]: assert builder_functions.get("bits") is not None builder_functions["bits"](value) elif lower_type in ["string"]: assert builder_functions.get("string") is not None builder_functions[lower_type](value) elif lower_type in ["bit"]: bits = [0 for _ in range(8)] bits[config["bit"] - 1] = int(value) log.debug(bits) builder.add_bits(bits) return builder.to_string() else: log.error("Unknown variable type") builder_converting_functions = { 5: builder.to_coils, 15: builder.to_coils, 6: builder.to_registers, 16: builder.to_registers } function_code = config["functionCode"] if function_code in builder_converting_functions: builder = builder_converting_functions[function_code]() if "Exception" in str(builder): log.exception(builder) builder = str(builder) return builder log.warning( "Unsupported function code, for the device %s in the Modbus Downlink converter", config["device"]) return None
def convert(self, config, data): byte_order = config["byteOrder"] if config.get("byteOrder") else "LITTLE" if byte_order == "LITTLE": builder = BinaryPayloadBuilder(byteorder=Endian.Little) elif byte_order == "BIG": builder = BinaryPayloadBuilder(byteorder=Endian.Big) else: log.warning("byte order is not BIG or LITTLE") return reg_count = config.get("registerCount", 1) value = config["value"] if config.get("tag") is not None: tags = (findall('[A-Z][a-z]*', config["tag"])) if "Coil" in tags: builder.add_bits(value) elif "String" in tags: builder.add_string(value) elif "Double" in tags: if reg_count == 4: builder.add_64bit_float(value) else: log.warning("unsupported amount of registers with double type for device %s in Downlink converter", self.__config["deviceName"]) return elif "Float" in tags: if reg_count == 2: builder.add_32bit_float(value) else: log.warning("unsupported amount of registers with float type for device %s in Downlink converter", self.__config["deviceName"]) return elif "Integer" in tags or "DWord" in tags or "DWord/Integer" in tags or "Word" in tags: if reg_count == 1: builder.add_16bit_int(value) elif reg_count == 2: builder.add_32bit_int(value) elif reg_count == 4: builder.add_64bit_int(value) else: log.warning("unsupported amount of registers with integer/word/dword type for device %s in Downlink converter", self.__config["deviceName"]) return else: log.warning("unsupported hardware data type for device %s in Downlink converter", self.__config["deviceName"]) if config.get("bit") is not None: bits = [0 for _ in range(8)] bits[config["bit"]-1] = int(value) log.debug(bits) builder.add_bits(bits) return builder.to_string() if config["functionCode"] in [5, 15]: return builder.to_coils() elif config["functionCode"] in [6, 16]: return builder.to_registers() else: log.warning("Unsupported function code, for device %s in Downlink converter", self.__config["deviceName"]) return
def convert(self, config, data): byte_order_str = config.get("byteOrder", "LITTLE") word_order_str = config.get("wordOrder", "LITTLE") byte_order = Endian.Big if byte_order_str.upper( ) == "BIG" else Endian.Little word_order = Endian.Big if word_order_str.upper( ) == "BIG" else Endian.Little repack = config.get("repack", False) builder = BinaryPayloadBuilder(byteorder=byte_order, wordorder=word_order, repack=repack) builder_functions = { "string": builder.add_string, "bits": builder.add_bits, "8int": builder.add_8bit_int, "16int": builder.add_16bit_int, "32int": builder.add_32bit_int, "64int": builder.add_64bit_int, "8uint": builder.add_8bit_uint, "16uint": builder.add_16bit_uint, "32uint": builder.add_32bit_uint, "64uint": builder.add_64bit_uint, "16float": builder.add_16bit_float, "32float": builder.add_32bit_float, "64float": builder.add_64bit_float } value = None if data.get("data") and data["data"].get("params") is not None: value = data["data"]["params"] else: value = config.get("value", 0) lower_type = config.get("type", config.get("tag", "error")).lower() if lower_type == "error": log.error('"type" and "tag" - not found in configuration.') variable_size = config.get( "objectsCount", config.get("registersCount", config.get("registerCount", 1))) * 16 if lower_type in ["integer", "dword", "dword/integer", "word", "int"]: lower_type = str(variable_size) + "int" assert builder_functions.get(lower_type) is not None builder_functions[lower_type](int(value)) elif lower_type in [ "uint", "unsigned", "unsigned integer", "unsigned int" ]: lower_type = str(variable_size) + "uint" assert builder_functions.get(lower_type) is not None builder_functions[lower_type](int(value)) elif lower_type in ["float", "double"]: lower_type = str(variable_size) + "float" assert builder_functions.get(lower_type) is not None builder_functions[lower_type](float(value)) elif lower_type in ["coil", "bits", "coils", "bit"]: assert builder_functions.get("bits") is not None if variable_size / 8 > 1.0: builder_functions["bits"](bytes(value, encoding='UTF-8')) if isinstance(value, str) else \ builder_functions["bits"](bytes(value)) else: return bytes(int(value)) elif lower_type in ["string"]: assert builder_functions.get("string") is not None builder_functions[lower_type](value) elif lower_type in builder_functions and 'int' in lower_type: builder_functions[lower_type](int(value)) elif lower_type in builder_functions and 'float' in lower_type: builder_functions[lower_type](float(value)) elif lower_type in builder_functions: builder_functions[lower_type](value) else: log.error("Unknown variable type") builder_converting_functions = { 5: builder.to_coils, 15: builder.to_coils, 6: builder.to_registers, 16: builder.to_registers } function_code = config["functionCode"] if function_code in builder_converting_functions: builder = builder_converting_functions[function_code]() log.debug(builder) if "Exception" in str(builder): log.exception(builder) builder = str(builder) if variable_size <= 16: if isinstance(builder, list) and len(builder) not in (8, 16, 32, 64): builder = builder[0] else: if isinstance(builder, list) and len(builder) not in (2, 4): log.warning( "There is a problem with the value builder. Only the first register is written." ) builder = builder[0] return builder log.warning( "Unsupported function code, for the device %s in the Modbus Downlink converter", config["device"]) return None
def convert(self, config, data): byte_order_str = config.get("byteOrder", "LITTLE") byte_order = Endian.Big if byte_order_str.upper( ) == "BIG" else Endian.Little builder = BinaryPayloadBuilder(byteorder=byte_order) builder_functions = { "string": builder.add_string, "bits": builder.add_bits, "8int": builder.add_8bit_int, "16int": builder.add_16bit_int, "32int": builder.add_32bit_int, "64int": builder.add_64bit_int, "8uint": builder.add_8bit_uint, "16uint": builder.add_16bit_uint, "32uint": builder.add_32bit_uint, "64uint": builder.add_64bit_uint, "16float": builder.add_16bit_float, "32float": builder.add_32bit_float, "64float": builder.add_64bit_float } value = config["value"] lower_type = config["tag"].lower() variable_size = config.get("registerCount", 1) * 8 if lower_type in ["integer", "dword", "dword/integer", "word"]: lower_type = str(variable_size) + "int" assert builder_functions.get(lower_type) is not None builder_functions[lower_type](value) elif lower_type in [ "uint", "unsigned", "unsigned integer", "unsigned int" ]: lower_type = str(variable_size) + "uint" assert builder_functions.get(lower_type) is not None builder_functions[lower_type](value) elif lower_type in ["float", "double"]: lower_type = str(variable_size) + "float" assert builder_functions.get(lower_type) is not None builder_functions[lower_type](value) elif lower_type in ["coil", "bits"]: assert builder_functions.get("bits") is not None builder_functions["bits"](value) elif lower_type in ["string"]: assert builder_functions.get("string") is not None builder_functions[lower_type](value) elif lower_type in ["bit"]: bits = [0 for _ in range(8)] bits[config["bit"] - 1] = int(value) log.debug(bits) builder.add_bits(bits) return builder.to_string() builder_converting_functions = { 5: builder.to_coils, 15: builder.to_coils, 6: builder.to_registers, 16: builder.to_registers } function_code = config["functionCode"] if function_code in builder_converting_functions: return builder_converting_functions[function_code]() log.warning( "Unsupported function code, for the device %s in the Modbus Downlink converter", self.__config["deviceName"]) return None