def testPayloadBuilderWithRawPayload(self): """ Test basic bit message encoding/decoding """ _coils1 = [False, False, True, True, False, True, False, False, False, False, False, True, False, False, True, False, False, True, True, True, True, False, False, False, False, True, False, True, False, True, True, False] _coils2 = [False, False, False, True, False, False, True, False, False, False, True, True, False, True, False, False, False, True, False, True, False, True, True, False, False, True, True, True, True, False, False, False] builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78'], repack=True) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([13330, 30806], builder.to_registers()) c = builder.to_coils() self.assertEqual(_coils1, c) builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78'], byteorder=Endian.Big) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([4660, 22136], builder.to_registers()) self.assertEqual('\x12\x34\x56\x78', str(builder)) c = builder.to_coils() self.assertEqual(_coils2, c)
def testPayloadBuilderWithRawPayload(self): """ Test basic bit message encoding/decoding """ _coils1 = [ False, False, True, True, False, True, False, False, False, False, False, True, False, False, True, False, False, True, True, True, True, False, False, False, False, True, False, True, False, True, True, False ] _coils2 = [ False, False, False, True, False, False, True, False, False, False, True, True, False, True, False, False, False, True, False, True, False, True, True, False, False, True, True, True, True, False, False, False ] builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78'], repack=True) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([13330, 30806], builder.to_registers()) c = builder.to_coils() self.assertEqual(_coils1, c) builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78'], byteorder=Endian.Big) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([4660, 22136], builder.to_registers()) self.assertEqual('\x12\x34\x56\x78', str(builder)) c = builder.to_coils() self.assertEqual(_coils2, c)
def testPayloadBuilderWithRawPayload(self): """ Test basic bit message encoding/decoding """ builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78']) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([13330, 30806], builder.to_registers()) builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78'], byteorder=Endian.Big) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([4660, 22136], builder.to_registers()) self.assertEqual('\x12\x34\x56\x78', str(builder))
def testPayloadBuilderReset(self): """ Test basic bit message encoding/decoding """ builder = BinaryPayloadBuilder() builder.add_8bit_uint(0x12) builder.add_8bit_uint(0x34) builder.add_8bit_uint(0x56) builder.add_8bit_uint(0x78) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([b'\x12\x34', b'\x56\x78'], builder.build()) builder.reset() self.assertEqual(b'', builder.to_string()) self.assertEqual([], builder.build())
def send(self, hex_list): builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) for hex_val in hex_list: builder.add_8bit_uint(hex_val) Modules.Utils.append_crc(builder) print('sending: ', builder.to_string()) payload = builder.build() for char in payload: self.client.send(char)
def testBigEndianPayloadBuilder(self): ''' Test basic bit message encoding/decoding ''' builder = BinaryPayloadBuilder(endian=Endian.Big) builder.add_8bit_uint(1) builder.add_16bit_uint(2) builder.add_32bit_uint(3) builder.add_64bit_uint(4) builder.add_8bit_int(-1) builder.add_16bit_int(-2) builder.add_32bit_int(-3) builder.add_64bit_int(-4) builder.add_32bit_float(1.25) builder.add_64bit_float(6.25) builder.add_string(b'test') builder.add_bits(self.bitstring) self.assertEqual(self.big_endian_payload, builder.to_string())
def testLittleEndianPayloadBuilder(self): """ Test basic bit message encoding/decoding """ builder = BinaryPayloadBuilder(byteorder=Endian.Little, wordorder=Endian.Little) builder.add_8bit_uint(1) builder.add_16bit_uint(2) builder.add_32bit_uint(3) builder.add_64bit_uint(4) builder.add_8bit_int(-1) builder.add_16bit_int(-2) builder.add_32bit_int(-3) builder.add_64bit_int(-4) builder.add_32bit_float(1.25) builder.add_64bit_float(6.25) builder.add_16bit_uint(1) # placeholder builder.add_string(b'test') builder.add_bits(self.bitstring) self.assertEqual(self.little_endian_payload, builder.to_string())
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") 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