def encode_field(self, value, mb_type='unit16'):
     builder = BinaryPayloadBuilder(endian=self.endian)
     if mb_type == 'bit' or mb_type == 'bits':
         builder.add_bits(value)
     elif mb_type == 'uint8':
         builder.add_8bit_uint(value)
     elif mb_type == 'uint16':
         builder.add_16bit_uint(value)
     elif mb_type == 'uint32':
         builder.add_32bit_uint(value)
     elif mb_type == 'uint64':
         builder.add_64bit_uint(value)
     elif mb_type == 'int8':
         builder.add_8bit_int(value)
     elif mb_type == 'int16':
         builder.add_16bit_int(value)
     elif mb_type == 'int32':
         builder.add_32bit_int(value)
     elif mb_type == 'int64':
         builder.add_64bit_int(value)
     elif mb_type == 'float32':
         builder.add_32bit_float(value)
     elif mb_type == 'float64':
         builder.add_64bit_float(value)
     elif mb_type == 'string' or mb_type == 'str':
         builder.add_string(value)
     else:
         log.warn('Not supported DataType: "%s"' % mb_type)
     return builder.build()
Exemplo n.º 2
0
    async def _write_register_value(
            self, key: str,
            value: Union[str, float, int]) -> WriteMultipleRegistersResponse:
        """Write a single value to the holding registers.

        Currently registers are written one at a time to avoid issues with
        discontinuous modbus addresses.

        """
        start_address = self.tags[key]['address']['start'] - 400001
        builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                       wordorder=Endian.Little)
        data_type = self.tags[key]['type']
        if data_type == 'float':
            builder.add_32bit_float(value)
        elif data_type == 'str':
            chars = self.tags[key]['length']
            if len(value) > chars:
                raise ValueError(f'{value} is too long for {key}. '
                                 f'Max: {chars} chars')
            builder.add_string(value.ljust(chars))
        elif data_type == 'int16':
            builder.add_16bit_int(value)
        elif data_type == 'int32':
            builder.add_32bit_int(value)
        else:
            raise ValueError("Missing data type.")
        resp = await self.write_registers(start_address,
                                          builder.build(),
                                          skip_encode=True)
        return resp[0]
Exemplo n.º 3
0
 def setSpeed(self, speed):  # Set up aim to speed and set up speed
     if self.mode != self.MODE_SPEED:
         self.mode = self.MODE_SPEED
     builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                    wordorder=Endian.Little)
     builder.add_16bit_int(int(speed))
     payload = builder.to_registers()[0]
     self.client.write_register(3, payload, unit=self.id)
Exemplo n.º 4
0
 def setPWM(self, pwm):  # Set up aim to pwm and set up pwm
     if self.mode != self.MODE_PWM:
         self.mode = self.MODE_NONE
         self.mode = self.MODE_PWM
     builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                    wordorder=Endian.Little)
     builder.add_16bit_int(int(pwm))
     payload = builder.to_registers()[0]
     self.client.write_register(2, payload, unit=self.id)
Exemplo n.º 5
0
 def loadsensorconfig(self, filename):
     d = np.load(filename)
     builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                    wordorder=Endian.Little)
     for i in d:
         builder.add_16bit_int(i)
     p = builder.build()
     for i, j in zip(p, range(len(d))):
         self.client.write_register(30 + j,
                                    i,
                                    skip_encode=True,
                                    unit=self.id)
Exemplo n.º 6
0
 def set_value(self, value):
     if value is not None:
         builder = BinaryPayloadBuilder(byteorder=self.byteorder,
                                        wordorder=self.wordorder)
         if self.encoding in ['int8', 'uint8']:
             builder.add_8bit_int(
                 value
             ) if self.encoding == 'int8' else builder.add_8bit_uint(
                 value)
         elif self.encoding in ['int16', 'uint16']:
             builder.add_16bit_int(
                 value
             ) if self.encoding == 'int16' else builder.add_16bit_uint(
                 value)
         elif self.encoding in ['int32', 'uint32']:
             builder.add_32bit_int(
                 value
             ) if self.encoding == 'int32' else builder.add_32bit_uint(
                 value)
         elif self.encoding in ['float32', 'float64']:
             builder.add_32bit_float(
                 value
             ) if self.encoding == 'float32' else builder.add_64bit_float(
                 value)
         elif self.encoding in ['int64', 'uint64']:
             builder.add_64bit_int(
                 value
             ) if self.encoding == 'int64' else builder.add_64bit_uint(
                 value)
         elif self.encoding == 'boolean':
             builder.add_16bit_uint(value)
         elif self.encoding == 'string':
             builder.add_string(value)
         else:
             log.error("Unhandled encoding exception {enc}".format(
                 enc=self.encoding))
         payload = builder.to_registers()
         log.info(
             "Setting {type} {addr} to {enc} {val} as {list}".format(
                 type=self.type,
                 addr=self.address,
                 enc=self.encoding,
                 val=value,
                 list=str(payload)))
         self.parent.context.setValues(self.get_function_code(),
                                       self.address, payload)
         self.value = value
     else:
         log.warning(
             "Attempt to set {type} {addr} to None (default={default})".
             format(type=self.type,
                    addr=self.address,
                    default=self.default))
 def updateData(self):
     if self.mode == self.MODE_ANGLE:
         builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                        wordorder=Endian.Little)
         builder.add_16bit_int(self.angle)
         payload = builder.to_registers()
         self.client.write_register(4, payload[0], unit=self.id)
     elif self.mode == self.MODE_SPEED:
         builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                        wordorder=Endian.Little)
         builder.add_16bit_int(self.speed)
         payload = builder.to_registers()[0]
         self.client.write_register(3, payload, unit=self.id)
Exemplo n.º 8
0
 def int_to_register(self, address, value):
     try:
         # Create a builder
         builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big)
         # Add num to builder
         builder.add_16bit_int(value)
         payload = builder.to_registers()
         payload = builder.build()
         registers = builder.to_registers()
         # Write value
         self.client.write_registers(address, registers, unit=1)
     except Exception as ex:
         print(ex)
Exemplo n.º 9
0
def run_payload_server():
    # ----------------------------------------------------------------------- #
    # build your payload
    # ----------------------------------------------------------------------- #
    builder = BinaryPayloadBuilder(byteorder=Endian.Little,
                                   wordorder=Endian.Little)
    builder.add_string('abcdefgh')
    builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0])
    builder.add_8bit_int(-0x12)
    builder.add_8bit_uint(0x12)
    builder.add_16bit_int(-0x5678)
    builder.add_16bit_uint(0x1234)
    builder.add_32bit_int(-0x1234)
    builder.add_32bit_uint(0x12345678)
    builder.add_16bit_float(12.34)
    builder.add_16bit_float(-12.34)
    builder.add_32bit_float(22.34)
    builder.add_32bit_float(-22.34)
    builder.add_64bit_int(-0xDEADBEEF)
    builder.add_64bit_uint(0x12345678DEADBEEF)
    builder.add_64bit_uint(0xDEADBEEFDEADBEED)
    builder.add_64bit_float(123.45)
    builder.add_64bit_float(-123.45)

    
    # ----------------------------------------------------------------------- #
    # use that payload in the data store
    # ----------------------------------------------------------------------- #
    # Here we use the same reference block for each underlying store.
    # ----------------------------------------------------------------------- #
    
    block = ModbusSequentialDataBlock(1, builder.to_registers())
    store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block)
    context = ModbusServerContext(slaves=store, single=True)
    
    # ----------------------------------------------------------------------- #
    # initialize the server information
    # ----------------------------------------------------------------------- #
    # If you don't set this or any fields, they are defaulted to empty strings.
    # ----------------------------------------------------------------------- #
    identity = ModbusDeviceIdentification()
    identity.VendorName = 'Pymodbus'
    identity.ProductCode = 'PM'
    identity.VendorUrl = 'http://github.com/riptideio/pymodbus/'
    identity.ProductName = 'Pymodbus Server'
    identity.ModelName = 'Pymodbus Server'
    identity.MajorMinorRevision = version.short()
    # ----------------------------------------------------------------------- #
    # run the server you want
    # ----------------------------------------------------------------------- #
    StartTcpServer(context, identity=identity, address=("localhost", 5020))
Exemplo n.º 10
0
def run_payload_server():
    # ----------------------------------------------------------------------- #
    # build your payload
    # ----------------------------------------------------------------------- #
    builder = BinaryPayloadBuilder(byteorder=Endian.Little,
                                   wordorder=Endian.Little)
    builder.add_string('abcdefgh')
    builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0])
    builder.add_8bit_int(-0x12)
    builder.add_8bit_uint(0x12)
    builder.add_16bit_int(-0x5678)
    builder.add_16bit_uint(0x1234)
    builder.add_32bit_int(-0x1234)
    builder.add_32bit_uint(0x12345678)
    builder.add_32bit_float(22.34)
    builder.add_32bit_float(-22.34)
    builder.add_64bit_int(-0xDEADBEEF)
    builder.add_64bit_uint(0x12345678DEADBEEF)
    builder.add_64bit_uint(0xDEADBEEFDEADBEED)
    builder.add_64bit_float(123.45)
    builder.add_64bit_float(-123.45)

    
    # ----------------------------------------------------------------------- #
    # use that payload in the data store
    # ----------------------------------------------------------------------- #
    # Here we use the same reference block for each underlying store.
    # ----------------------------------------------------------------------- #
    
    block = ModbusSequentialDataBlock(1, builder.to_registers())
    store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block)
    context = ModbusServerContext(slaves=store, single=True)
    
    # ----------------------------------------------------------------------- #
    # initialize the server information
    # ----------------------------------------------------------------------- #
    # If you don't set this or any fields, they are defaulted to empty strings.
    # ----------------------------------------------------------------------- #
    identity = ModbusDeviceIdentification()
    identity.VendorName = 'Pymodbus'
    identity.ProductCode = 'PM'
    identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
    identity.ProductName = 'Pymodbus Server'
    identity.ModelName = 'Pymodbus Server'
    identity.MajorMinorRevision = '1.5'
    # ----------------------------------------------------------------------- #
    # run the server you want
    # ----------------------------------------------------------------------- #
    StartTcpServer(context, identity=identity, address=("localhost", 5020))
Exemplo n.º 11
0
def change_station_id(modbusid, serialport, id_setting, current_baudrate):
    instrument = ModbusSerialClient(method='rtu',
                                    port=serialport,
                                    baudrate=current_baudrate)

    builder = BinaryPayloadBuilder(byteorder=Endian.Big)

    builder.add_16bit_int(id_setting)
    payload = builder.build()

    pld = payload[0][1] | (payload[0][0] << 8)

    instrument.connect()
    instrument.write_register(1000, pld, unit=modbusid, timeout=.1)
    instrument.close()
 def testLittleEndianPayloadBuilder(self):
     ''' Test basic bit message encoding/decoding '''
     builder = BinaryPayloadBuilder(endian=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_string('test')
     builder.add_bits(self.bitstring)
     self.assertEqual(self.little_endian_payload, str(builder))
Exemplo n.º 13
0
 def testLittleEndianPayloadBuilder(self):
     ''' Test basic bit message encoding/decoding '''
     builder = BinaryPayloadBuilder(endian=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_string('test')
     builder.add_bits(self.bitstring)
     self.assertEqual(self.little_endian_payload, str(builder))
Exemplo n.º 14
0
 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())
Exemplo n.º 15
0
    def write_register(self,register_name,value, unit=None):
        """
        :param register_name: register key from holding register dictionary
            generated by yaml config
        :param value: value to write to register
        :returns: -- Nothing
        """
        # TODO add the ability to discern which settings will be appropriate for
        # the device that is being written to
        if (unit is None):
            unit = self.UNIT_ID
        '''
        builder = BinaryPayloadBuilder(byteorder=self.BYTE_ORDER,
            wordorder=self.WORD_ORDER_DICT[unit])
        '''
        builder = BinaryPayloadBuilder(byteorder=self.BYTE_ORDER_DICT[unit],
            wordorder=self.WORD_ORDER_DICT[unit])
        # This will change depending on the device that is being connected
        # potentially so it has to be correleated to the device ID

        if (self.holding_register_dict[register_name][1] == '8int'):
            builder.add_8bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '8uint'):
            builder.add_8bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '16int'):
            builder.add_16bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '16uint'):
            builder.add_16bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '32int'):
            builder.add_32bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '32uint'):
            builder.add_32bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '32float'):
            builder.add_32bit_float(value)
        elif (self.holding_register_dict[register_name][1] == '64int'):
            builder.add_64bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '64uint'):
            builder.add_64bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '64float'):
            builder.add_64bit_float(value)
        else:
            print("Bad type")
            exit()
        payload = builder.build()
        self.client.write_registers(self.holding_register_dict[register_name][0],
            payload, skip_encode=True, unit = self.UNIT_ID)
Exemplo n.º 16
0
 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())
Exemplo n.º 17
0
 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())
Exemplo n.º 18
0
def change_tracker_setpoint(modbusid, serialport, setpoint):
    instrument = ModbusSerialClient(method='rtu',
                                    port=serialport,
                                    baudrate=9600)

    builder = BinaryPayloadBuilder(endian=Endian.Big)

    builder.add_16bit_int(setpoint)
    payload = builder.build()
    #print(payload)

    #print(payload[0][0])
    #print(payload[0][1])

    pld = payload[0][1] | (payload[0][0] << 8)

    instrument.connect()
    instrument.write_register(3, pld, unit=modbusid, timeout=.1)
    instrument.close()
Exemplo n.º 19
0
class PayloadHandler:
    """
    encodes/decodes values according to the way it is stored in registry
    SCALE stands for multiplying/dividing by a scaling factor
    COMB stands for storing the value of one field in two registers
    if none of those provided encodes only based on the type
    """
    def __init__(self, env, store):
        self.byte_order = env["byte_order"]
        self.word_order = env["word_order"]
        self.d_s_factor = env["default_scaling_factor"]
        self.battery_store = store
        self.builder = BinaryPayloadBuilder(byteorder=self.byte_order,
                                            wordorder=self.word_order)

    def encode(self, value, encoding):
        self.builder.reset()
        encode_type = {
            INT8: lambda x: self.builder.add_8bit_int(x),
            UINT8: lambda x: self.builder.add_8bit_uint(x),
            INT16: lambda x: self.builder.add_16bit_int(x),
            UINT16: lambda x: self.builder.add_16bit_uint(x),
            INT32: lambda x: self.builder.add_32bit_int(x),
            UINT32: lambda x: self.builder.add_32bit_uint(x),
            FLOAT32: lambda x: self.builder.add_32bit_float(x),
        }
        if 'e_type' not in encoding or encoding['e_type'] == COMB:
            encode_type[encoding['d_type']](value)
        else:
            encode_type[encoding['d_type']](round(
                value * encoding.get('s_factor', self.d_s_factor)))
        return self.builder.to_registers()

    def decode(self, fx, addr, encoding):
        encoded_value = self.battery_store.getValues(fx, addr, 2)
        decoder = BinaryPayloadDecoder.fromRegisters(encoded_value,
                                                     byteorder=self.byte_order,
                                                     wordorder=self.word_order)
        decode_type = {
            INT8: lambda: decoder.decode_8bit_int(),
            UINT8: lambda: decoder.decode_8bit_uint(),
            INT16: lambda: decoder.decode_16bit_int(),
            UINT16: lambda: decoder.decode_16bit_uint(),
            INT32: lambda: decoder.decode_32bit_int(),
            UINT32: lambda: decoder.decode_32bit_uint(),
            FLOAT32: lambda: decoder.decode_32bit_float(),
        }
        if 'e_type' not in encoding or encoding['e_type'] == COMB:
            return decode_type[encoding['d_type']]()
        else:
            return decode_type[encoding['d_type']]() / encoding.get(
                's_factor', self.d_s_factor)
Exemplo n.º 20
0
    def build_args(self, arg, kwargs):
        builder = BinaryPayloadBuilder(
            byteorder=Endian.Big)  #, wordorder=Endian.Big)
        if 'arg_type' in kwargs:
            if kwargs['arg_type'] == 'float': builder.add_32bit_float(arg)
            elif kwargs['arg_type'] == 'uint64': builder.add_64bit_uint(arg)
            elif kwargs['arg_type'] == 'int64': builder.add_64bit_int(arg)
            elif kwargs['arg_type'] == 'uint32': builder.add_32bit_uint(arg)
            elif kwargs['arg_type'] == 'int32': builder.add_32bit_int(arg)
            elif kwargs['arg_type'] == 'uint16': builder.add_16bit_uint(arg)
            elif kwargs['arg_type'] == 'int16': builder.add_16bit_int(arg)
            elif kwargs['arg_type'] == 'int8': builder.add_8bit_int(arg)
            elif kwargs['arg_type'] == 'uint8': builder.add_8bit_uint(arg)
            elif kwargs['arg_type'] == 'string': builder.add_string(arg)
            else:
                raise Exception("unknown parameter type given: %s" %
                                (kwargs['arg_type']))
        else:
            builder.add_16bit_uint(arg)

        val = builder.build()
        return val
Exemplo n.º 21
0
    def run(self) -> None:
        builder = BinaryPayloadBuilder(byteorder=self.endian,
                                       wordorder=self.endian)
        builder.add_32bit_uint(42)
        builder.add_16bit_uint(12)
        builder.add_32bit_int(64)
        builder.add_16bit_int(128)
        builder.add_32bit_float(256)

        store = ModbusSlaveContext(
            di=ModbusSequentialDataBlock(18476, builder.to_registers()),
            co=ModbusSequentialDataBlock(18476, builder.to_registers()),
            hr=ModbusSequentialDataBlock(18476, builder.to_registers()),
            ir=ModbusSequentialDataBlock(18476, builder.to_registers()),
            zero_mode=True
        )

        slaves = {
            0x01: store,
            0x02: store,
            0x03: store,
            0x04: store,
        }

        # context = ModbusServerContext(slaves=store, single=True)
        context = ModbusServerContext(slaves=slaves, single=False)

        identity = ModbusDeviceIdentification()
        identity.VendorName = 'Pymodbus'
        identity.ProductCode = 'PM'
        identity.VendorUrl = 'http://github.com/riptideio/pymodbus/'
        identity.ProductName = 'Pymodbus Server'
        identity.ModelName = 'Pymodbus Server'
        identity.MajorMinorRevision = '2.3.0'

        framer = ModbusSocketFramer

        self.server = ModbusTcpServer(context, framer, identity, address=("127.0.0.1", self.port))
        self.server.serve_forever()
Exemplo n.º 22
0
    def write_register(self,register_name,value, unit=None):
        """
        :param register_name: register key from holding register dictionary
            generated by yaml config
        :param value: value to write to register
        :returns: -- Nothing
        """
        if (unit is None):
            unit = self.UNIT_ID

        builder = BinaryPayloadBuilder(byteorder=self.BYTE_ORDER,
            wordorder=self.WORD_ORDER)
        if (self.holding_register_dict[register_name][1] == '8int'):
            builder.add_8bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '8uint'):
            builder.add_8bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '16int'):
            builder.add_16bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '16uint'):
            builder.add_16bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '32int'):
            builder.add_32bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '32uint'):
            builder.add_32bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '32float'):
            builder.add_32bit_float(value)
        elif (self.holding_register_dict[register_name][1] == '64int'):
            builder.add_64bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '64uint'):
            builder.add_64bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '64float'):
            builder.add_64bit_float(value)
        else:
            print("Bad type")
            exit()
        payload = builder.build()
        self.client.write_registers(self.holding_register_dict[register_name][0], payload, skip_encode=True, unit = self.UNIT_ID)
Exemplo n.º 23
0
 def initialize(self):
     print("Attempting to initialize {}".format(self.identifier))
     builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                    wordorder=Endian.Big)
     builder.add_16bit_int(0)
     builder.add_16bit_int(self.multiplier)
     builder.add_16bit_int(1)
     command = self.sync_client.write_registers(TARGET_SELECT,
                                                builder.to_registers(),
                                                unit=self.address)
     if command.isError():
         print("Could not initialize {}. Reason: {}".format(
             self.identifier, command))
         self.initialized = False
     else:
         print("Initialized {}".format(self.identifier))
         self.initialized = True
Exemplo n.º 24
0
 def writeRegister(self, reg, data):
     builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                    wordorder=Endian.Little)
     builder.add_16bit_int(data)
     payload = builder.to_registers()[0]
     self.client.write_register(reg, payload, unit=self.id)
Exemplo n.º 25
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
Exemplo n.º 26
0
 def setPWM_Limit(self, i):
     builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                    wordorder=Endian.Little)
     builder.add_16bit_int(i)
     payload = builder.to_registers()[0]
     self.client.write_register(21, payload, unit=self.id)
Exemplo n.º 27
0
def run_binary_payload_ex():
    # ----------------------------------------------------------------------- #
    # We are going to use a simple client to send our requests
    # ----------------------------------------------------------------------- #
    client = ModbusClient('127.0.0.1', port=5020)
    client.connect()
    
    # ----------------------------------------------------------------------- #
    # If you need to build a complex message to send, you can use the payload
    # builder to simplify the packing logic.
    #
    # Here we demonstrate packing a random payload layout, unpacked it looks
    # like the following:
    #
    # - a 8 byte string 'abcdefgh'
    # - a 32 bit float 22.34
    # - a 16 bit unsigned int 0x1234
    # - another 16 bit unsigned int 0x5678
    # - an 8 bit int 0x12
    # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
    # - an 32 bit uint 0x12345678
    # - an 32 bit signed int -0x1234
    # - an 64 bit signed int 0x12345678

    # The packing can also be applied to the word (wordorder) and bytes in each
    # word (byteorder)

    # The wordorder is applicable only for 32 and 64 bit values
    # Lets say we need to write a value 0x12345678 to a 32 bit register

    # The following combinations could be used to write the register

    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #
    # Word Order - Big                      Byte Order - Big
    # word1 =0x1234 word2 = 0x5678

    # Word Order - Big                      Byte Order - Little
    # word1 =0x3412 word2 = 0x7856

    # Word Order - Little                   Byte Order - Big
    # word1 = 0x5678 word2 = 0x1234

    # Word Order - Little                   Byte Order - Little
    # word1 =0x7856 word2 = 0x3412
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #

    # ----------------------------------------------------------------------- #
    builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                   wordorder=Endian.Little)
    builder.add_string('abcdefgh')
    builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0])
    builder.add_8bit_int(-0x12)
    builder.add_8bit_uint(0x12)
    builder.add_16bit_int(-0x5678)
    builder.add_16bit_uint(0x1234)
    builder.add_32bit_int(-0x1234)
    builder.add_32bit_uint(0x12345678)
    builder.add_32bit_float(22.34)
    builder.add_32bit_float(-22.34)
    builder.add_64bit_int(-0xDEADBEEF)
    builder.add_64bit_uint(0x12345678DEADBEEF)
    builder.add_64bit_uint(0x12345678DEADBEEF)
    builder.add_64bit_float(123.45)
    builder.add_64bit_float(-123.45)
    payload = builder.to_registers()
    print("-" * 60)
    print("Writing Registers")
    print("-" * 60)
    print(payload)
    print("\n")
    payload = builder.build()
    address = 0
    # Can write registers
    # registers = builder.to_registers()
    # client.write_registers(address, registers, unit=1)

    # Or can write encoded binary string
    client.write_registers(address, payload, skip_encode=True, unit=1)
    # ----------------------------------------------------------------------- #
    # If you need to decode a collection of registers in a weird layout, the
    # payload decoder can help you as well.
    #
    # Here we demonstrate decoding a random register layout, unpacked it looks
    # like the following:
    #
    # - a 8 byte string 'abcdefgh'
    # - a 32 bit float 22.34
    # - a 16 bit unsigned int 0x1234
    # - another 16 bit unsigned int which we will ignore
    # - an 8 bit int 0x12
    # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
    # ----------------------------------------------------------------------- #
    address = 0x0
    count = len(payload)
    result = client.read_holding_registers(address, count,  unit=1)
    print("-" * 60)
    print("Registers")
    print("-" * 60)
    print(result.registers)
    print("\n")
    decoder = BinaryPayloadDecoder.fromRegisters(result.registers,
                                                 byteorder=Endian.Little,
                                                 wordorder=Endian.Little)

    decoded = OrderedDict([
        ('string', decoder.decode_string(8)),
        ('bits', decoder.decode_bits()),
        ('8int', decoder.decode_8bit_int()),
        ('8uint', decoder.decode_8bit_uint()),
        ('16int', decoder.decode_16bit_int()),
        ('16uint', decoder.decode_16bit_uint()),
        ('32int', decoder.decode_32bit_int()),
        ('32uint', decoder.decode_32bit_uint()),
        ('32float', decoder.decode_32bit_float()),
        ('32float2', decoder.decode_32bit_float()),
        ('64int', decoder.decode_64bit_int()),
        ('64uint', decoder.decode_64bit_uint()),
        ('ignore', decoder.skip_bytes(8)),
        ('64float', decoder.decode_64bit_float()),
        ('64float2', decoder.decode_64bit_float()),
    ])

    print("-" * 60)
    print("Decoded Data")
    print("-" * 60)
    for name, value in iteritems(decoded):
        print("%s\t" % name, hex(value) if isinstance(value, int) else value)
    
    # ----------------------------------------------------------------------- #
    # close the client
    # ----------------------------------------------------------------------- #
    client.close()
Exemplo n.º 28
0
 def write(self, name, value):
     client = self.mbclient(host=self.host,
                            port=self.port,
                            retries=self.retries,
                            backoff=self.backoff,
                            timeout=self.timeout,
                            framer=self.mbframer,
                            retry_on_empty=True,
                            retry_on_invalid=True)
     if not client.connect():
         logger.error("Cannot connect to bridge %s" % (self.host))
         return False
     row = list(filter(lambda r: r[0] == name, self.mapping))
     if len(row):
         (name, descr, unit, datatype, rw, scale, offset, register) = row[0]
         if not rw:
             logger.error(
                 "Error writing to bridge %s slave %d register %d: read only"
                 % (self.host, self.slaveid, register))
             client.close()
             return False
         register = int(register)
         try:
             builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                            wordorder=self.endian)
             if datatype == 'b':
                 builder.add_8bit_int(value)
             if datatype == 'B':
                 builder.add_8bit_uint(value)
             if datatype == 'h':
                 builder.add_16bit_int(value)
             if datatype == 'H':
                 builder.add_16bit_uint(value)
             if datatype == 'i':
                 builder.add_32bit_int(value)
             if datatype == 'I':
                 builder.add_32bit_uint(value)
             if datatype == 'q':
                 builder.add_64bit_int(value)
             if datatype == 'Q':
                 builder.add_64bit_uint(value)
             if datatype == 'f':
                 builder.add_32bit_float(value)
             if datatype == 'd':
                 builder.add_64bit_float(value)
             if re.match(r'^s(\d*)$', datatype):
                 builder.add_string(value)
             registers = builder.to_registers()
         except (AttributeError, ValueError, struct.error) as e:
             logger.error(
                 "Error writing to bridge %s slave %d register %d: %s" %
                 (self.host, self.slaveid, register, str(e)))
             client.close()
             return False
         try:
             if register > 40000:
                 addr = register - 40001
                 if len(registers) > 1:
                     result = client.write_registers(addr,
                                                     registers,
                                                     unit=self.slaveid)
                 else:
                     result = client.write_register(addr,
                                                    value,
                                                    unit=self.slaveid)
             else:
                 addr = register - 1
                 result = client.write_coil(addr,
                                            bool(value),
                                            unit=self.slaveid)
         except ConnectionException as e:
             logger.error(
                 "Error writing to bridge %s slave %d register %d: %s" %
                 (self.host, self.slaveid, register, str(e)))
             client.close()
             return False
         if type(result) == ExceptionResponse:
             logger.error(
                 "Error writing to bridge %s slave %d register %d: %s" %
                 (self.host, self.slaveid, register, result))
             client.close()
             return False
         if result.isError():
             logger.error(
                 "Error writing to bridge %s slave %d register %d" %
                 (self.host, self.slaveid, register))
             client.close()
             return False
         logger.debug(
             'Modbus bridge: %s slave: %s register: %s (%s) value: %s' %
             (self.host, self.slaveid, register, name, value))
     client.close()
     return True
Exemplo n.º 29
0
            for meter in meters:
                address = confparser[meter].getint(
                    "dst_address",
                    fallback=default_config["meters"]["dst_address"])
                meter_type = confparser[meter].get(
                    "type", fallback=default_config["meters"]["type"])
                meter_module = importlib.import_module(f"devices.{meter_type}")
                meter_device = meter_module.device(confparser[meter])

                slave_ctx = ModbusSlaveContext()

                block_1601 = BinaryPayloadBuilder(byteorder=Endian.Big,
                                                  wordorder=Endian.Little)
                block_1601.add_32bit_int(1234)  # config passcode
                block_1601.add_16bit_int(confparser[meter].getint(
                    "ct_current",
                    fallback=default_config["meters"]
                    ["ct_current"]))  # ct rated current
                block_1601.add_16bit_int(confparser[meter].getint(
                    "ct_current",
                    fallback=default_config["meters"]
                    ["ct_current"]))  # ct rated current l1
                block_1601.add_16bit_int(confparser[meter].getint(
                    "ct_current",
                    fallback=default_config["meters"]
                    ["ct_current"]))  # ct rated current l2
                block_1601.add_16bit_int(confparser[meter].getint(
                    "ct_current",
                    fallback=default_config["meters"]
                    ["ct_current"]))  # ct rated current l3
                block_1601.add_16bit_int(confparser[meter].getint(
                    "ct_inverted",
Exemplo n.º 30
0
def run_binary_payload_ex():
    # ----------------------------------------------------------------------- #
    # We are going to use a simple client to send our requests
    # ----------------------------------------------------------------------- #
    client = ModbusClient('127.0.0.1', port=5020)
    client.connect()
    
    # ----------------------------------------------------------------------- #
    # If you need to build a complex message to send, you can use the payload
    # builder to simplify the packing logic.
    #
    # Here we demonstrate packing a random payload layout, unpacked it looks
    # like the following:
    #
    # - a 8 byte string 'abcdefgh'
    # - a 32 bit float 22.34
    # - a 16 bit unsigned int 0x1234
    # - another 16 bit unsigned int 0x5678
    # - an 8 bit int 0x12
    # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
    # - an 32 bit uint 0x12345678
    # - an 32 bit signed int -0x1234
    # - an 64 bit signed int 0x12345678

    # The packing can also be applied to the word (wordorder) and bytes in each
    # word (byteorder)

    # The wordorder is applicable only for 32 and 64 bit values
    # Lets say we need to write a value 0x12345678 to a 32 bit register

    # The following combinations could be used to write the register

    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #
    # Word Order - Big                      Byte Order - Big
    # word1 =0x1234 word2 = 0x5678

    # Word Order - Big                      Byte Order - Little
    # word1 =0x3412 word2 = 0x7856

    # Word Order - Little                   Byte Order - Big
    # word1 = 0x5678 word2 = 0x1234

    # Word Order - Little                   Byte Order - Little
    # word1 =0x7856 word2 = 0x3412
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #

    # ----------------------------------------------------------------------- #
    combos = [(wo, bo) for wo in [Endian.Big, Endian.Little] for bo in [Endian.Big, Endian.Little]]
    for wo, bo in combos:
        print("-" * 60)
        print("Word Order: {}".format(ORDER_DICT[wo]))
        print("Byte Order: {}".format(ORDER_DICT[bo]))
        print()
        builder = BinaryPayloadBuilder(byteorder=bo,
                                       wordorder=wo)
        strng = "abcdefgh"
        builder.add_string(strng)
        builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0])
        builder.add_8bit_int(-0x12)
        builder.add_8bit_uint(0x12)
        builder.add_16bit_int(-0x5678)
        builder.add_16bit_uint(0x1234)
        builder.add_32bit_int(-0x1234)
        builder.add_32bit_uint(0x12345678)
        builder.add_16bit_float(12.34)
        builder.add_16bit_float(-12.34)
        builder.add_32bit_float(22.34)
        builder.add_32bit_float(-22.34)
        builder.add_64bit_int(-0xDEADBEEF)
        builder.add_64bit_uint(0x12345678DEADBEEF)
        builder.add_64bit_uint(0x12345678DEADBEEF)
        builder.add_64bit_float(123.45)
        builder.add_64bit_float(-123.45)
        payload = builder.to_registers()
        print("-" * 60)
        print("Writing Registers")
        print("-" * 60)
        print(payload)
        print("\n")
        payload = builder.build()
        address = 0
        # Can write registers
        # registers = builder.to_registers()
        # client.write_registers(address, registers, unit=1)

        # Or can write encoded binary string
        client.write_registers(address, payload, skip_encode=True, unit=1)
        # ----------------------------------------------------------------------- #
        # If you need to decode a collection of registers in a weird layout, the
        # payload decoder can help you as well.
        #
        # Here we demonstrate decoding a random register layout, unpacked it looks
        # like the following:
        #
        # - a 8 byte string 'abcdefgh'
        # - a 32 bit float 22.34
        # - a 16 bit unsigned int 0x1234
        # - another 16 bit unsigned int which we will ignore
        # - an 8 bit int 0x12
        # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
        # ----------------------------------------------------------------------- #
        address = 0x0
        count = len(payload)
        result = client.read_holding_registers(address, count,  unit=1)
        print("-" * 60)
        print("Registers")
        print("-" * 60)
        print(result.registers)
        print("\n")
        decoder = BinaryPayloadDecoder.fromRegisters(result.registers,
                                                     byteorder=bo,
                                                     wordorder=wo)

        assert decoder._byteorder == builder._byteorder, \
                "Make sure byteorder is consistent between BinaryPayloadBuilder and BinaryPayloadDecoder"

        assert decoder._wordorder == builder._wordorder, \
                "Make sure wordorder is consistent between BinaryPayloadBuilder and BinaryPayloadDecoder"


        decoded = OrderedDict([
            ('string', decoder.decode_string(len(strng))),
            ('bits', decoder.decode_bits()),
            ('8int', decoder.decode_8bit_int()),
            ('8uint', decoder.decode_8bit_uint()),
            ('16int', decoder.decode_16bit_int()),
            ('16uint', decoder.decode_16bit_uint()),
            ('32int', decoder.decode_32bit_int()),
            ('32uint', decoder.decode_32bit_uint()),
            ('16float', decoder.decode_16bit_float()),
            ('16float2', decoder.decode_16bit_float()),
            ('32float', decoder.decode_32bit_float()),
            ('32float2', decoder.decode_32bit_float()),
            ('64int', decoder.decode_64bit_int()),
            ('64uint', decoder.decode_64bit_uint()),
            ('ignore', decoder.skip_bytes(8)),
            ('64float', decoder.decode_64bit_float()),
            ('64float2', decoder.decode_64bit_float()),
        ])

        print("-" * 60)
        print("Decoded Data")
        print("-" * 60)
        for name, value in iteritems(decoded):
            print("%s\t" % name, hex(value) if isinstance(value, int) else value)
    
    # ----------------------------------------------------------------------- #
    # close the client
    # ----------------------------------------------------------------------- #
    client.close()
Exemplo n.º 31
0
    def write(self):
        try: 
            lb = 00000000
            hb = 00000000
            #### byte besteht immer aus 16 bits
            for byte in self._db['out']:
                for bit in sorted(self._db['out'][byte]):  
                    if bit in self._db['out'][byte]:
                        bitpos =    bit[0]                                                          #startbit/bitposition des binärwertes
                        type =      bit[1]
                        value =     bit[2]
                        name =      bit[3]
                        bit[2] =    bit[3]()                                                        ##aktueller wert des items abrufen und value updaten!
                        builder = BinaryPayloadBuilder(endian=Endian.Little)

                        ##unterscheidung dateityp
                        if type == '5' or type == '5.001' or type == '6' :                          ##8bit uint / int
                            length = 8
                            if bitpos < 8:  #lb
                                lb = value
                            else:           #hb
                                hb = value
                                
                            if type == '5':
                                builder.add_8bit_uint(lb)
                                builder.add_8bit_uint(hb)
                                #logger.debug('MODBUS: 8bit uint {0} ; {1}'.format(lb,hb)) 
                            elif type == '5.001':                            ##0-100 in 0-255 umwandeln!
                                #print(dpts.en5001(lb))
                                #print(dpts.en5001(hb))
                                
                                lb = self.de5001(lb)
                                hb = self.de5001(hb)
                                #print("lb geschrieben", lb )
                                #print("hb geschrieben", hb )
                                builder.add_8bit_uint(lb)
                                builder.add_8bit_uint(hb)
                                #logger.debug('MODBUS: 8bit uint {0} ; {1}'.format(lb,hb)) 
                            elif type == '6':
                                if lb > 127:
                                    lb = 127
                                elif lb < -128:
                                    lb = -128
                                if hb > 127:
                                    hb = 127
                                elif hb < -128:
                                    hb = -128
                                builder.add_8bit_int(lb)
                                builder.add_8bit_int(hb)
                                #logger.debug('MODBUS: 8bit int {0} ; {1}'.format(lb.hb)) 
                        elif type == '7' or type == '8':                                            #16bit uint / int
                            length = 16
                            if type == '7':                                                         #0...65535
                                builder.add_16bit_uint(value)
                                #logger.debug('MODBUS: 16bit uint {0} '.format(value)) 
                            else:                                                                   #-32768...32767
                                builder.add_16bit_int(value)   
                                #logger.debug('MODBUS: 16bit int {0}'.format(value)) 
                            
                        elif type == '1':
                            length = 1
                                                                                                    #nur pro byte einmal die bits wandeln
                            if bitpos < 8:  #lb
                                lb  = lb | int(value) << bitpos
                                #logger.debug('MODBUS: 8bit int{0}'.format(lb)) 
                                
                            else:           #hb
                                hb  = hb | int(value) << bitpos
                                #logger.debug('MODBUS: 8bit int{0}'.format(hb)) 
                                
                            builder.add_8bit_uint(lb)
                            builder.add_8bit_uint(hb)
                            
                payload = builder.build()
                logger.debug('MODBUS: write to PLC: WORD {0} set to {1} '.format(byte,payload)) 
                self._modbuspy.write_registers(byte, payload, skip_encode=True)
                builder.reset()        
        except Exception as e:
            logger.error('MODBUS: Could not write an OutWord, because {}'.format(e))
            self._lock.release()
            return None
Exemplo n.º 32
0
 def _pack(value):
     builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                    wordorder=Endian.Little)
     builder.add_16bit_int(int(value))
     return builder.build()
Exemplo n.º 33
0
 def setAngle_PWM_limit(self, i):  #PWM increase limit in angle control loop
     builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                    wordorder=Endian.Little)
     builder.add_16bit_int(i)
     payload = builder.to_registers()[0]
     self.client.write_register(22, payload, unit=self.id)
def prefil_registers(a):
    context=a[0]
    # Values to be filled:
    # 4000 SERIAL NUMBER, length 2, 13070001 HEX
    # 4002 MeterCode, length 1, 0102 HEX
    # 4003 Meter ID, Length 1, 0001
    # 4004 Baud, Length 1, 9600
    # 4005 Protocol Version, Lenth 2, 3.2
    # 4007 Software Version, Length 2, 1.18
    # 4009 Hardware Version, Length 2, 1.03
    # 400B Meter Amps, Length 1, 45
    # 400D S0 Rate, Length 2, 1000
    # 400F Combination Code, Length 1, 10 (Forward - Reverse)
    # 4010 LCD LifeCycle, Lenght 1, 01 HEX
    # 4011 Parity Setting, Length 1, 01
    # 4012 Current Direction, Lenght 1, FW ASCII

    builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                   wordorder=Endian.Big)
    builder.add_32bit_float(0x13070001)
    builder.add_16bit_int(0x0102)
    builder.add_16bit_int(1)
    builder.add_16bit_int(9600)
    builder.add_32bit_float(3.2)
    builder.add_32bit_float(1.18)
    builder.add_32bit_float(1.03)
    builder.add_16bit_int(45)
#    builder.add_16bit_int(0)
    payload = builder.to_registers()
    context[0x01].setValues(0x10, 0x4000, payload)
    # Skip Address
    builder2 = BinaryPayloadBuilder(byteorder=Endian.Big,
                                   wordorder=Endian.Big)
    builder2.add_32bit_float(1000)
    builder2.add_16bit_int(10)
    builder2.add_16bit_int(0x10)
    builder2.add_16bit_int(01)
    builder2.add_string('FW')
    payload2 = builder2.to_registers()
    context[0x01].setValues(0x10, 0x400D, payload2)

    # 5000
    builder3 = BinaryPayloadBuilder(byteorder=Endian.Big,
                                   wordorder=Endian.Big)
    builder3.add_32bit_float(230)
    builder3.add_32bit_float(230)
    builder3.add_32bit_float(230)
    builder3.add_32bit_float(230)
    builder3.add_32bit_float(50)
    payload3 = builder3.to_registers()
    context[0x01].setValues(0x10, 0x5000, payload3)
Exemplo n.º 35
0
class MbVariable:
    def __init__(self, name, var_type, encoding, scale, offset):
        self.name = name
        # do not allow invalid encoding
        if encoding not in [
                "BB", "LB", "BL", "LL", "ABCD", "CDAB", "BADC", "DCBA"
        ]:
            logging.error("invalid Encoding:" + encoding + " For " + name)
            raise KeyError
        self.encoding = encoding
        self.type, self.size = compute_size(var_type)
        self.value = 0
        self.bpb = None
        self.bpd = None
        self.scale = float(scale)
        self.offset = float(offset)
        self.registers = [0] * self.size
        self.set_builder()
        self.register = None

    def __str__(self):
        return self.name

    def set_var_register(self, reg):
        # print("decoding ", self.name, self.type, reg)
        if self.encoding in ['BB', 'ABCD']:
            self.bpd = BinaryPayloadDecoder.fromRegisters(reg,
                                                          byteorder=Endian.Big,
                                                          wordorder=Endian.Big)
        elif self.encoding in ['BL', 'CDAB']:
            self.bpd = BinaryPayloadDecoder.fromRegisters(
                reg, byteorder=Endian.Big, wordorder=Endian.Little)
        elif self.encoding in ['LL', 'DCBA']:
            self.bpd = BinaryPayloadDecoder.fromRegisters(
                reg, byteorder=Endian.Little, wordorder=Endian.Little)
        elif self.encoding in ['LB', 'BADC']:
            self.bpd = BinaryPayloadDecoder.fromRegisters(
                reg, byteorder=Endian.Little, wordorder=Endian.Big)
        else:
            raise KeyError
        self.register = reg

        if self.type == "uint16":
            val = self.bpd.decode_16bit_uint() * self.scale + int(self.offset)
        elif self.type in ["sint16", "int16"]:
            val = self.bpd.decode_16bit_int() * self.scale + int(self.offset)
        elif self.type in ["uint32"]:
            val = self.bpd.decode_32bit_uint() * self.scale + int(self.offset)
        elif self.type in ["sint32", "int32"]:
            val = self.bpd.decode_32bit_int() * self.scale + int(self.offset)
        elif self.type in ["float32"]:
            val = self.bpd.decode_32bit_float() * self.scale + int(self.offset)
        elif self.type == "str":
            val1 = self.bpd.decode_string(self.size)
            val = val1.decode()
        else:
            logging.error("Unknown data type" + self.type)
            raise KeyError
        if math.isnan(val):
            self.value = 0
        else:
            self.value = val

    def set_builder(self):
        if self.encoding in ['BB', 'ABCD']:
            self.bpb = BinaryPayloadBuilder(byteorder=Endian.Big,
                                            wordorder=Endian.Big)
        elif self.encoding in ['BL', 'CDAB']:
            self.bpb = BinaryPayloadBuilder(byteorder=Endian.Big,
                                            wordorder=Endian.Little)
        elif self.encoding in ['LL', 'DCBA']:
            self.bpb = BinaryPayloadBuilder(byteorder=Endian.Little,
                                            wordorder=Endian.Little)
        elif self.encoding in ['LB', 'BADC']:
            self.bpb = BinaryPayloadBuilder(byteorder=Endian.Little,
                                            wordorder=Endian.Big)
        else:
            raise KeyError

    def set_value(self, value):
        self.set_builder()
        self.set_reg_value(value)
        self.value = value

    def set_reg_value(self, value):
        if self.type == "uint16":
            v_raw = int((float(value) - self.offset) / self.scale)
            if v_raw < 0:
                logging.warning("Negative value for " + self.name + ":" +
                                str(v_raw))
                v_raw = 0
            self.bpb.add_16bit_uint(v_raw)
        elif self.type == "int16":
            self.bpb.add_16bit_int(
                int((float(value) - self.offset) / self.scale))
        elif self.type == "uint32":
            v_raw = int((float(value) - self.offset) / self.scale)
            if v_raw < 0:
                logging.warning("Negative value for " + self.name + ":" +
                                str(v_raw))
                v_raw = 0
            self.bpb.add_32bit_uint(v_raw)
        elif self.type == "int32":
            self.bpb.add_32bit_int(
                int((float(value) - self.offset) / self.scale))
        elif self.type == "float32":
            self.bpb.add_32bit_float(
                int((float(value) - self.offset) / self.scale))
        elif self.type == "str":
            value_str = " " * (self.size - len(str(value))) + str(value)
            self.bpb.add_string(value_str)
        else:
            logging.error("Unknown format:" + self.type + " for " + self.name)
            raise ValueError
        self.registers = self.bpb.to_registers()
        logging.debug("Updated var register " + str(self.registers))