def run_server(): store = ModbusSlaveContext( di=ModbusSequentialDataBlock(0, [17] * 100), co=ModbusSequentialDataBlock(0, [17] * 100), hr=ModbusSequentialDataBlock(0, [17] * 100), ir=ModbusSequentialDataBlock(0, [17] * 100), ) context = ModbusServerContext(slaves=store, single=True) 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() # socat -d -d PTY,link=/tmp/ptyp0,raw,echo=0,ispeed=9600 PTY,link=/tmp/ttyp0,raw,echo=0,ospeed=9600 StartSerialServer( context, framer=ModbusRtuFramer, identity=identity, port="/tmp/ttyp0", timeout=0.005, baudrate=9600, )
def run_dbstore_update_server(): # ----------------------------------------------------------------------- # # initialize your data store # ----------------------------------------------------------------------- # block = ModbusSequentialDataBlock(0x00, [0] * 0xff) store = SqlSlaveContext(block) context = ModbusServerContext(slaves={1: store}, single=False) # ----------------------------------------------------------------------- # # initialize the server information # ----------------------------------------------------------------------- # 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 # ----------------------------------------------------------------------- # time = 5 # 5 seconds delay loop = LoopingCall(f=updating_writer, a=(context,)) loop.start(time, now=False) # initially delay by time loop.stop() StartTcpServer(context, identity=identity, address=("", 5020))
def run_server(): store = ModbusSlaveContext( di=ModbusSequentialDataBlock(0, [17] * 100), co=ModbusSequentialDataBlock(0, [17] * 100), hr=ModbusSequentialDataBlock(0, [17] * 100), ir=ModbusSequentialDataBlock(0, [17] * 100), ) context = ModbusServerContext(slaves=store, single=True) 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() StartTlsServer( context, identity=identity, certfile="server.crt", keyfile="server.key", address=("127.0.0.1", 8020), )
def run_callback_server(): # ----------------------------------------------------------------------- # # initialize your data store # ----------------------------------------------------------------------- # queue = Queue() devices = read_device_map("device-mapping") block = CallbackDataBlock(devices, queue) store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block) context = ModbusServerContext(slaves=store, single=True) # ----------------------------------------------------------------------- # # initialize the server information # ----------------------------------------------------------------------- # 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 # ----------------------------------------------------------------------- # p = Process(target=device_writer, args=(queue,)) p.start() StartTcpServer(context, identity=identity, address=("localhost", 5020))
def create_identity(cls, vendor="Pymodbus", product_code="PM", vendor_url='http://github.com/riptideio/pymodbus/', product_name="Pymodbus Server", model_name="Reactive Server", version=pymodbus_version.short()): """ Create modbus identity :param vendor: :param product_code: :param vendor_url: :param product_name: :param model_name: :param version: :return: ModbusIdentity object """ identity = ModbusDeviceIdentification() identity.VendorName = vendor identity.ProductCode = product_code identity.VendorUrl = vendor_url identity.ProductName = product_name identity.ModelName = model_name identity.MajorMinorRevision = version return identity
def run_updating_server(): # ----------------------------------------------------------------------- # # initialize your data store # ----------------------------------------------------------------------- # store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [17] * 100), co=ModbusSequentialDataBlock(0, [17] * 100), hr=ModbusSequentialDataBlock(0, [17] * 100), ir=ModbusSequentialDataBlock(0, [17] * 100)) context = ModbusServerContext(slaves=store, single=True) # ----------------------------------------------------------------------- # # initialize the server information # ----------------------------------------------------------------------- # 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 # ----------------------------------------------------------------------- # time = 5 # 5 seconds delay loop = LoopingCall(f=updating_writer, a=(context, )) loop.start(time, now=False) # initially delay by time StartTcpServer(context, identity=identity, address=("localhost", 5020))
def __configure_and_run_slave(config): identity = None if config.get('identity'): identity = ModbusDeviceIdentification() identity.VendorName = config['identity'].get('vendorName', '') identity.ProductCode = config['identity'].get('productCode', '') identity.VendorUrl = config['identity'].get('vendorUrl', '') identity.ProductName = config['identity'].get('productName', '') identity.ModelName = config['identity'].get('ModelName', '') identity.MajorMinorRevision = version.short() blocks = {} for (key, value) in config.get('values').items(): values = {} converter = BytesModbusDownlinkConverter({}) for item in value: for section in ('attributes', 'timeseries', 'attributeUpdates', 'rpc'): for val in item.get(section, []): function_code = FUNCTION_CODE_WRITE[key][0] if val['objectsCount'] <= 1 else \ FUNCTION_CODE_WRITE[key][1] converted_value = converter.convert( {**val, 'device': config.get('deviceName', 'Gateway'), 'functionCode': function_code, 'byteOrder': config['byteOrder']}, {'data': {'params': val['value']}}) values[val['address'] + 1] = converted_value blocks[FUNCTION_TYPE[key]] = ModbusSparseDataBlock(values) context = ModbusServerContext(slaves=ModbusSlaveContext(**blocks), single=True) SLAVE_TYPE[config['type']](context, identity=identity, address=(config.get('host'), config.get('port')) if ( config['type'] == 'tcp' or 'udp') else None, port=config.get('port') if config['type'] == 'serial' else None, framer=FRAMER_TYPE[config['method']])
def run_server(): store = ModbusSlaveContext( di=ModbusSequentialDataBlock(0, [17] * 100), co=ModbusSequentialDataBlock(0, [17] * 100), hr=ModbusSequentialDataBlock(0, [17] * 100), ir=ModbusSequentialDataBlock(0, [17] * 100)) store.register(CustomModbusRequest.function_code, 'cm', ModbusSequentialDataBlock(0, [17] * 100)) 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 # ----------------------------------------------------------------------- # # Tcp: StartTcpServer(context, identity=identity, address=("localhost", 5020), custom_functions=[CustomModbusRequest])
def run_server(): # ----------------------------------------------------------------------- # # initialize your data store # ----------------------------------------------------------------------- # store = ModbusSlaveContext() 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() # ----------------------------------------------------------------------- # # Add an example which is long enough to force the ReadDeviceInformation # request / response to require multiple responses to send back all of the # information. # ----------------------------------------------------------------------- # identity[0x80] = "Lorem ipsum dolor sit amet, consectetur adipiscing " \ "elit. Vivamus rhoncus massa turpis, sit amet " \ "ultrices orci semper ut. Aliquam tristique sapien in " \ "lacus pharetra, in convallis nunc consectetur. Nunc " \ "velit elit, vehicula tempus tempus sed. " # ----------------------------------------------------------------------- # # Add an example with repeated object IDs. The MODBUS specification is # entirely silent on whether or not this is allowed. In practice, this # should be assumed to be contrary to the MODBUS specification and other # clients (other than pymodbus) might behave differently when presented # with an object ID occurring twice in the returned information. # # Use this at your discretion, and at the very least ensure that all # objects which share a single object ID can fit together within a single # ADU unit. In the case of Modbus RTU, this is about 240 bytes or so. In # other words, when the spec says "An object is indivisible, therefore # any object must have a size consistent with the size of transaction # response", if you use repeated OIDs, apply that rule to the entire # grouping of objects with the repeated OID. # ----------------------------------------------------------------------- # identity[0x81] = [ 'pymodbus {0}'.format(pymodbus_version), 'pyserial {0}'.format(pyserial_version) ] # ----------------------------------------------------------------------- # # run the server you want # ----------------------------------------------------------------------- # # Tcp: StartTcpServer(context, identity=identity, address=("localhost", 5020))
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))
from pymodbus.device import ModbusDeviceIdentification from pymodbus.datastore import ModbusSequentialDataBlock from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext from twisted.internet import reactor # ------------------------------------------------------------ # initialize the identity # ------------------------------------------------------------ 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() # ------------------------------------------------------------ # initialize the datastore # ------------------------------------------------------------ store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [17] * 100), co=ModbusSequentialDataBlock(0, [17] * 100), hr=ModbusSequentialDataBlock(0, [17] * 100), ir=ModbusSequentialDataBlock(0, [17] * 100)) context = ModbusServerContext(slaves=store, single=True) # ------------------------------------------------------------ # initialize the factory # ------------------------------------------------------------ address = ("", Defaults.Port) factory = ModbusServerFactory(context, None, identity)
def run_server(): # ----------------------------------------------------------------------- # # initialize your data store # ----------------------------------------------------------------------- # # The datastores only respond to the addresses that they are initialized to # Therefore, if you initialize a DataBlock to addresses of 0x00 to 0xFF, a # request to 0x100 will respond with an invalid address exception. This is # because many devices exhibit this kind of behavior (but not all):: # # block = ModbusSequentialDataBlock(0x00, [0]*0xff) # # Continuing, you can choose to use a sequential or a sparse DataBlock in # your data context. The difference is that the sequential has no gaps in # the data while the sparse can. Once again, there are devices that exhibit # both forms of behavior:: # # block = ModbusSparseDataBlock({0x00: 0, 0x05: 1}) # block = ModbusSequentialDataBlock(0x00, [0]*5) # # Alternately, you can use the factory methods to initialize the DataBlocks # or simply do not pass them to have them initialized to 0x00 on the full # address range:: # # store = ModbusSlaveContext(di = ModbusSequentialDataBlock.create()) # store = ModbusSlaveContext() # # Finally, you are allowed to use the same DataBlock reference for every # table or you may use a separate DataBlock for each table. # This depends if you would like functions to be able to access and modify # the same data or not:: # # block = ModbusSequentialDataBlock(0x00, [0]*0xff) # store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block) # # The server then makes use of a server context that allows the server to # respond with different slave contexts for different unit ids. By default # it will return the same context for every unit id supplied (broadcast # mode). # However, this can be overloaded by setting the single flag to False and # then supplying a dictionary of unit id to context mapping:: # # slaves = { # 0x01: ModbusSlaveContext(...), # 0x02: ModbusSlaveContext(...), # 0x03: ModbusSlaveContext(...), # } # context = ModbusServerContext(slaves=slaves, single=False) # # The slave context can also be initialized in zero_mode which means that a # request to address(0-7) will map to the address (0-7). The default is # False which is based on section 4.4 of the specification, so address(0-7) # will map to (1-8):: # # store = ModbusSlaveContext(..., zero_mode=True) # ----------------------------------------------------------------------- # store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [17] * 100), co=ModbusSequentialDataBlock(0, [17] * 100), hr=ModbusSequentialDataBlock(0, [17] * 100), ir=ModbusSequentialDataBlock(0, [17] * 100)) 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 # ----------------------------------------------------------------------- # # Tcp: StartTcpServer(context, identity=identity, address=("", 5020))
def run_server(): # ----------------------------------------------------------------------- # # initialize your data store # ----------------------------------------------------------------------- # # The datastores only respond to the addresses that they are initialized to # Therefore, if you initialize a DataBlock to addresses of 0x00 to 0xFF, a # request to 0x100 will respond with an invalid address exception. This is # because many devices exhibit this kind of behavior (but not all):: # # block = ModbusSequentialDataBlock(0x00, [0]*0xff) # # Continuing, you can choose to use a sequential or a sparse DataBlock in # your data context. The difference is that the sequential has no gaps in # the data while the sparse can. Once again, there are devices that exhibit # both forms of behavior:: # block = ModbusSparseDataBlock({ # aux soc 0x101: 0b01011111, # aux v 0x102: 141, # 0.1V # aux a 0x103: 3309, # 0.01A # controller temperature 0x104: 0b0001010100001111, # H: ctrl temp, L: battery temp sensor # altenator voltage 0x105: 146, # 0.1V # altenator amps 0x106: 4000, #0.01A # altenator watts 0x107: 496, # solar v 0x108: 304, # solar a 0x109: 20, # solar w 0x10A: 6684, 0x10B: 0, # lowest battery V in day 0x10C: 108, # 0.1 # max battery V in day 0x10D: 144, # max battery A in day 0x10E: 5000, #0.01A 0x10F: 0, 0x110: 0, 0x111: 0, 0x112: 0, 0x113: 0, 0x114: 0, 0x115: 0, # running day count 0x116: 1, 0x117: 0, # number of times battery is full in day 0x118: 3, 0x119: 0, 0x11A: 0, 0x11B: 0, 0x11C: 0, 0x11D: 0, 0x11E: 0, 0x11F: 0, 0x120: 0, # charge state (L) 0x121: 0b0000000010001010, 0x122: 0, 0x123: 0, }) # block = ModbusSequentialDataBlock(0x00, [0]*5) # # Alternately, you can use the factory methods to initialize the DataBlocks # or simply do not pass them to have them initialized to 0x00 on the full # address range:: # # store = ModbusSlaveContext(di = ModbusSequentialDataBlock.create()) # store = ModbusSlaveContext() # # Finally, you are allowed to use the same DataBlock reference for every # table or you may use a separate DataBlock for each table. # This depends if you would like functions to be able to access and modify # the same data or not:: # # block = ModbusSequentialDataBlock(0x00, [0]*0xff) # store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block) # # The server then makes use of a server context that allows the server to # respond with different slave contexts for different unit ids. By default # it will return the same context for every unit id supplied (broadcast # mode). # However, this can be overloaded by setting the single flag to False and # then supplying a dictionary of unit id to context mapping:: # store = ModbusSlaveContext(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() StartSerialServer( context, framer=ModbusRtuFramer, identity=identity, port='/dev/ttyUSB0', timeout=.05, baudrate=9600, stopbits=2, bytesize=8)