Exemplo n.º 1
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]
 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.º 3
0
 def set_target(self, target):
     builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                    wordorder=Endian.Big)
     builder.add_32bit_int(target)
     request = self.sync_client.write_registers(SET_MOTOR_TARGET,
                                                builder.to_registers(),
                                                unit=self.address)
     return not request.isError()
Exemplo n.º 4
0
    def setAngle(self, angle):  # Set up aim to angle and set up angle
        if self.mode != self.MODE_ANGLE:
            self.mode = self.MODE_ANGLE

        builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                       wordorder=Endian.Little)
        builder.add_32bit_int(int(angle))
        payload = builder.build()
        self.client.write_registers(4, payload, skip_encode=True, unit=self.id)
Exemplo n.º 5
0
    def sendInt(self, address, value):
        """Send a 32 bit value to the first modbus unit.
        Parameters: value and address where the value will be
        stored in.
        Return: Result if it was successful or not.
        """
        builder = BinaryPayloadBuilder(byteorder=Endian.Big)
        builder.add_32bit_int(value)
        payload = builder.build()

        return self.client.write_register(address, value, unit=1)
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))
Exemplo n.º 7
0
def make_block(section, test_val, test_params):
    #print("Format", section)
    builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                   wordorder=Endian.Big)
    # TYPES TO BE ADDED
    value = 0
    data_size = 0
    for s in section:
        field_name = test_params["field_name"].format(source=s[4], block=s[5], field=s[6] )
        #print(field_name, test_val[field_name], s)
        print("Add: ", data_size, s, end="")
        value = test_val[field_name]
        #value += 1
        if s[0] == "float16":
            builder.add_16bit_uint(round(value) ) 
            data_size +=1
        elif s[0] == "uint16":
            #print(value, float(value), s[2] , s[3] )
            #print("values:", s, value)
            val = int( ( float(value) - float(s[3])) / float(s[2]) )
            #print("values:", s, value, val)
            builder.add_16bit_uint(val)
            data_size+=1
        elif s[0] == "uint32":
            val = int(float(value) / float(s[2]) - float(s[3]) )
            builder.add_32bit_uint(val)
            data_size += 2
        elif s[0] in ["int32", "sint32"]:
            val = int(float(value) / float(s[2]) - float(s[3]) )
            builder.add_32bit_int(val)
            data_size +=2
        elif s[0] == "float32":
            val = float(value)  / float(s[2]) - float(s[3]) 
            builder.add_32bit_float(val)
            data_size +=2
        elif s[0] == "bit16":
            builder.add_bits([0, 0, 0, 0, 0, 0, 0, 0] )
            builder.add_bits([0, 0, 0, 0, 0, 0, 0, 0] )
            val = 0
            data_size += 1
        elif s[0][:3] == "str":
            data_length = int(s[1])
            val = " " * (data_length - len(str(value))) + str(value)
            builder.add_string(val)
            data_size += data_length/2
        else:
            print(" ------ ", s) 
        print(val)
        #value += 1

    block = ModbusSequentialDataBlock(1, builder.to_registers())
    return block
Exemplo n.º 8
0
 def set_target(self, target):
     """
     Sets the target for the motor
     :param target: Units of acceleration measured in SMunits. Please use the converter class to convert from desired units to steps.
     :return: Boolean indicating if the write was successful
     """
     builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                    wordorder=Endian.Big)
     builder.add_32bit_int(target)
     request = self.modbus_client.write_registers(SET_MOTOR_TARGET,
                                                  builder.to_registers(),
                                                  unit=self.address)
     return not request.isError()
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 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(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 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.º 15
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.º 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 sendModbus(address, value, type):
    global modbusClient
    if (modbusClient.connect() == False):
        print("Modbus connection lost, trying to reconnect...")
        ModbusClient(modbusInverterIP,
                     port=502,
                     unit_id=3,
                     auto_open=True,
                     auto_close=True)
        print("Modbus Connected: {}".format(modbusClient.connect()))
    else:
        # SMA expects everything in Big Endian format
        builder = BinaryPayloadBuilder(byteorder=Endian.Big,
                                       wordorder=Endian.Big)
        # Only unsigned int32 and signed int32 are built in. It is enough to control the flow of power of the battery.
        if (type == "uint32"):
            builder.add_32bit_uint(value)
        if (type == "int32"):
            builder.add_32bit_int(value)
        registers = builder.to_registers()
        modbusClient.write_registers(address, registers, unit=3)
Exemplo n.º 18
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.º 19
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.º 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 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.º 22
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.º 23
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"]
def makeMotionParameter():
    # Direct運転 P.292, P.351
    builder = BinaryPayloadBuilder(byteorder=Endian.Big)
    builder.add_32bit_int(0)
    builder.add_32bit_int(method)
    builder.add_32bit_int(position)
    builder.add_32bit_int(speed)
    builder.add_32bit_int(changeSpeed)
    builder.add_32bit_int(stop)
    builder.add_32bit_int(motionSupply)
    # builder.add_32bit_int(feedbackTrigger)
    builder.add_32bit_int(
        AZDKDDirectParameter.FeedbackTrigger["AllDataFeedback"])
    builder.add_32bit_int(transportDestination)

    # builder.add_32bit_int(0)
    # builder.add_32bit_int(1)
    # builder.add_32bit_int(8500)
    # builder.add_32bit_int(2000)
    # builder.add_32bit_int(1500)
    # builder.add_32bit_int(1500)
    # builder.add_32bit_int(100)
    # builder.add_32bit_int(1)
    return builder.build()
Exemplo n.º 25
0
client = ModbusClient(method="rtu",
                      port="/dev/ttyXRUSB0",
                      stopbits=1,
                      bytesize=8,
                      parity='E',
                      baudrate=9600,
                      timeout=0.01)
connection = client.connect()
print(connection)

#FW方向回転開始
print("start fw")
#################################################################################################################
#回転速度(No.0)の設定
builder = BinaryPayloadBuilder(byteorder=Endian.Little)  #Endian big1?
builder.add_32bit_int(1000)  #代入したい数値(10進数)#200r/min
result = client.write_registers(address=0x0480,
                                values=builder.build(),
                                unit=0x01,
                                skip_encode=True)
print(result)
#address : 囲みたいレジスタの最初のアドレス
#unit : 送信相手のID

#回転開始
builder = BinaryPayloadBuilder(byteorder=Endian.Big)
builder.add_32bit_int(
    0b00101000
)  #代入したい数値(10進数)#0x007C : 0b00000000,00000000 0x007D : 0b00000000,00101000
result = client.write_registers(address=0x007C,
                                values=builder.build(),
Exemplo n.º 26
0
def getPayload(num):
    builder = BinaryPayloadBuilder(byteorder=Endian.Big)
    builder.add_32bit_int(num)
    return builder.build()
Exemplo n.º 27
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))
Exemplo n.º 28
0
def makeMotionParameter():
    builder = BinaryPayloadBuilder(byteorder=Endian.Big)
    builder.add_32bit_int(method)  # 方式(基準アドレス+0,1)
    builder.add_32bit_int(position)  # 位置(基準アドレス+2, 3)
    builder.add_32bit_int(speed)  # 速度(基準アドレス+4, 5)
    builder.add_32bit_int(changeSpeed)  # 起動・変速(基準アドレス+6, 7)
    builder.add_32bit_int(stop)  # 停止(基準アドレス+8, 9)
    builder.add_32bit_int(motionSupply)  # 運転電流(基準アドレス+10 11)
    builder.add_32bit_int(motionFinishDelay)  # 運転終了遅延(基準アドレス+12, 13)
    builder.add_32bit_int(merge)  # 結合(基準アドレス+14, 15)
    builder.add_32bit_int(mergeTo)  # 結合先(基準アドレス+16, 17)
    builder.add_32bit_int(offsetArea)  # オフセット(エリア)(基準アドレス+18, 19)
    builder.add_32bit_int(widthArea)  # 幅(エリア)(基準アドレス+20, 21)
    builder.add_32bit_int(countLoop)  # カウント(loop) (基準アドレス+22, 23)
    builder.add_32bit_int(postionOffset)  # 位置オフセット(基準アドレス+24, 25)
    builder.add_32bit_int(finishLoop)  # 終了(loop)(基準アドレス+26, 27)
    builder.add_32bit_int(weakEvent)  # 弱イ.ベント(基準アドレス+28, 29)
    builder.add_32bit_int(strongEvent)  # 強イベント(基準ドレス+30, 31)
    return builder.build()
Exemplo n.º 29
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.º 30
0
    def __write_Registers(self, regPara, value):
        objectType = regPara['objectType']
        address = regPara['regAddr']
        slaveUnit = regPara['slaveUnit']
        bo = regPara['byteOrder']
        wo = regPara['wordOrder']
        dataTypeStr = regPara['dataType']
        dataType = ''.join(
            filter(str.isalpha, dataTypeStr
                   ))  # vom dataType die Ziffen entfernen z.B. uint16 = uint
        registerCount = 0  # Anzahl der zu schreibenden Register (Words)

        try:
            bits = int(''.join(filter(
                str.isdigit,
                dataTypeStr)))  # bit-Zahl aus aus dataType z.B. uint16 = 16
        except:
            bits = 16

        if dataType.lower() == 'string':
            registerCount = int(
                bits / 2
            )  # bei string: bits = bytes !! string16 -> 16Byte - 8 registerCount
        else:
            registerCount = int(bits / 16)

        if regPara['factor'] != 1:
            #self.logger.debug("value {0} divided by: {1}".format(value, regPara['factor']))
            value = value * (1 / regPara['factor'])

        self.logger.debug(
            "write {0} to {1}.{2}.{3} (address.slaveUnit) dataType:{4}".format(
                value, objectType, address, slaveUnit, dataTypeStr))
        builder = BinaryPayloadBuilder(byteorder=bo, wordorder=wo)

        if dataType.lower() == 'uint':
            if bits == 16:
                builder.add_16bit_uint(int(value))
            elif bits == 32:
                builder.add_32bit_uint(int(value))
            elif bits == 64:
                builder.add_64bit_uint(int(value))
            else:
                self.logger.error(
                    "Number of bits or datatype not supportet : {0}".format(
                        typeStr))
        elif dataType.lower() == 'int':
            if bits == 16:
                builder.add_16bit_int(int(value))
            elif bits == 32:
                builder.add_32bit_int(int(value))
            elif bits == 64:
                builder.add_64bit_int(int(value))
            else:
                self.logger.error(
                    "Number of bits or datatype not supportet : {0}".format(
                        typeStr))
        elif dataType.lower() == 'float':
            if bits == 32:
                builder.add_32bit_float(value)
            if bits == 64:
                builder.add_64bit_float(value)
            else:
                self.logger.error(
                    "Number of bits or datatype not supportet : {0}".format(
                        typeStr))
        elif dataType.lower() == 'string':
            builder.add_string(value)
        elif dataType.lower() == 'bit':
            if objectType == 'Coil' or objectType == 'DiscreteInput':
                if not type(value) == type(True):  # test is boolean
                    self.logger.error(
                        "Value is not boolean: {0}".format(value))
                    return
            else:
                if set(bitstr).issubset({
                        '0', '1'
                }) and bool(bitstr):  # test is bit-string '00110101'
                    builder.add_bits(value)
                else:
                    self.logger.error(
                        "Value is not a bitstring: {0}".format(value))
        else:
            self.logger.error(
                "Number of bits or datatype not supportet : {0}".format(
                    typeStr))
            return None

        if objectType == 'Coil':
            result = self._Mclient.write_coil(address, value, unit=slaveUnit)
        elif objectType == 'HoldingRegister':
            registers = builder.to_registers()
            result = self._Mclient.write_registers(address,
                                                   registers,
                                                   unit=slaveUnit)
        elif objectType == 'DiscreteInput':
            self.logger.warning(
                "this object type cannot be written {0}:{1} slaveUnit:{2}".
                format(objectType, address, slaveUnit))
            return
        elif objectType == 'InputRegister':
            self.logger.warning(
                "this object type cannot be written {0}:{1} slaveUnit:{2}".
                format(objectType, address, slaveUnit))
            return
        else:
            return
        if result.isError():
            self.logger.error(
                "write error: {0} {1}.{2}.{3} (address.slaveUnit)".format(
                    result, objectType, address, slaveUnit))
            return None

        if 'write_dt' in regPara:
            regPara['last_write_dt'] = regPara['write_dt']
            regPara['write_dt'] = datetime.now()
        else:
            regPara.update({'write_dt': datetime.now()})

        if 'write_value' in regPara:
            regPara['last_write_value'] = regPara['write_value']
            regPara['write_value'] = value
        else:
            regPara.update({'write_value': value})
Exemplo n.º 31
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
def run_binary_payload_ex():
    # ----------------------------------------------------------------------- #
    # We are going to use a simple client to send our requests
    # ----------------------------------------------------------------------- #
    client = ModbusClient('127.0.0.1', port=5440)
    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.Little,
                                   wordorder=Endian.Big)
    builder.add_string('abcdefgh')
    builder.add_32bit_float(22.34)
    builder.add_16bit_uint(0x1234)
    builder.add_16bit_uint(0x5678)
    builder.add_8bit_int(0x12)
    builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0])
    builder.add_32bit_uint(0x12345678)
    builder.add_32bit_int(-0x1234)
    builder.add_64bit_int(0x1234567890ABCDEF)
    payload = builder.build()
    address = 0
    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 = 0x00
    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.Big)
    decoded = {
        'string': decoder.decode_string(8),
        'float': decoder.decode_32bit_float(),
        '16uint': decoder.decode_16bit_uint(),
        'ignored': decoder.skip_bytes(2),
        '8int': decoder.decode_8bit_int(),
        'bits': decoder.decode_bits(),
        "32uints": decoder.decode_32bit_uint(),
        "32ints": decoder.decode_32bit_int(),
        "64ints": decoder.decode_64bit_int(),
    }
    
    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.º 33
0
        print("Decoded Data")
        print("-" * 60)
        for name, value in decoded.items():
            print ("%s\t" % name, value)
        print("\n")

        # Try to write registers 2000
        print("-" * 60)
        print("Writing Registers")
        print("-" * 60)

        builder = BinaryPayloadBuilder(byteorder='>', wordorder='>')
        
        builder.add_16bit_uint(1234)
        builder.add_16bit_uint(0) # Skip 1 byte        
        builder.add_32bit_int(-1234)
        builder.add_32bit_float(-1.234)
        builder.add_32bit_float(54961.85)
        builder.add_16bit_int(-5678)
        builder.add_16bit_uint(0) # Skip 1 byte
        builder.add_32bit_uint(1)
        
        payload = builder.to_registers()
        print("\n")
        print(payload)
        print("\n")
        payload = builder.build()
        # Can write registers
        registers = builder.to_registers()
        response = client.write_registers(2000, registers, unit=1)
        print(response)