コード例 #1
0
    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
コード例 #2
0
    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
コード例 #3
0
    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
コード例 #4
0
    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
コード例 #5
0
    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