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
 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.º 3
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.º 4
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.º 5
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.º 7
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.º 8
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.º 9
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.º 10
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.º 11
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.º 12
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.º 13
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.º 14
0
# 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
# - an 8 bit int 0x12
# - an 8 bit bitstring [0,1,0,1,1,0,1,0]
# ---------------------------------------------------------------------------#
builder = BinaryPayloadBuilder(endian=Endian.Little)
builder.add_string("abcdefgh")
builder.add_32bit_float(22.34)
builder.add_16bit_uint(0x1234)
builder.add_8bit_int(0x12)
builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0])
payload = builder.build()
address = 0x01
result = client.write_registers(address, payload, skip_encode=True)

# ---------------------------------------------------------------------------#
# 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
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.º 16
0
#from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadBuilder
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

#builder_di = BinaryPayloadBuilder()
#builder_di.add_bits([1,1,1,1,1,1,1,1])

# [heater,cooler,...]
builder_co = BinaryPayloadBuilder()
builder_co.add_bits([0, 0, 0, 0, 0, 0, 0, 0])

# temperature
builder_hr = BinaryPayloadBuilder()
builder_hr.add_8bit_int(70)

# wanted to use input registers for temperature, but they are read only
#builder_ir = BinaryPayloadBuilder()
#builder_ir.add_8bit_int(70)

#di_block = ModbusSequentialDataBlock(0x01, builder_di.to_coils())
co_block = ModbusSequentialDataBlock(0x101, builder_co.to_coils())
hr_block = ModbusSequentialDataBlock(0x201, builder_hr.to_registers())
#ir_block = ModbusSequentialDataBlock(0x301, builder_ir.to_registers())

#store = ModbusSlaveContext(di=di_block, co=co_block, hr=hr_block, ir=ir_block)
store = ModbusSlaveContext(co=co_block, hr=hr_block)
context = ModbusServerContext(slaves=store, single=True)

identity = ModbusDeviceIdentification()
Exemplo n.º 17
0
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

builder_di = BinaryPayloadBuilder()
#builder.add_bits([0,0,0,1,1,0,1,1])
builder_di.add_bits([1, 1, 1, 1, 1, 1, 1, 1])

builder_co = BinaryPayloadBuilder()
#builder.add_bits([0,0,0,0,1,1,1,1])
builder_co.add_bits([0, 0, 0, 0, 0, 0, 0, 0])

builder_hr = BinaryPayloadBuilder()
builder_hr.add_string('abcdefgh')

builder_ir = BinaryPayloadBuilder()
builder_ir.add_8bit_int(33)

di_block = ModbusSequentialDataBlock(0x01, builder_di.to_coils())
co_block = ModbusSequentialDataBlock(0x101, builder_co.to_coils())
hr_block = ModbusSequentialDataBlock(0x201, builder_hr.to_registers())
ir_block = ModbusSequentialDataBlock(0x301, builder_ir.to_registers())

store = ModbusSlaveContext(di=di_block, co=co_block, hr=hr_block, ir=ir_block)
context = ModbusServerContext(slaves=store, single=True)

identity = ModbusDeviceIdentification()
identity.VendorName = 'Pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
identity.ProductName = 'Pymodbus Server'
identity.ModelName = 'Pymodbus Server'
Exemplo n.º 18
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.º 19
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.º 20
0
#---------------------------------------------------------------------------#
# configure the service logging
#---------------------------------------------------------------------------#
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

#---------------------------------------------------------------------------#
# build your payload
#---------------------------------------------------------------------------#
builder = BinaryPayloadBuilder(endian=Endian.Little)
builder.add_string('abcdefgh')
builder.add_32bit_float(22.34)
builder.add_16bit_uint(0x1234)
builder.add_8bit_int(0x12)
builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0])

#---------------------------------------------------------------------------#
# 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
#---------------------------------------------------------------------------#
Exemplo n.º 21
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