Beispiel #1
0
def modbus_master(module, properties):
    log.debug('Modbus master module : '  + str(module))
    # Modbus Master
    #--------------------------------------------------------------------------#
    # initialize your data store
    #--------------------------------------------------------------------------#
    store = ModbusSlaveContext(
        co = ModbusSequentialDataBlock(0, [0]*100),
        hr = ModbusSequentialDataBlock(0, [0]*100))
    context = ModbusServerContext(slaves=store, single=True)

    #--------------------------------------------------------------------------#
    # initialize the server information
    #--------------------------------------------------------------------------#
    identity = ModbusDeviceIdentification()
    identity.VendorName  = 'ASO+AKO'
    identity.ProductCode = 'DYODE'
    identity.VendorUrl   = 'yoloswag'
    identity.ProductName = 'DYODE'
    identity.ModelName   = 'BSides LV release'
    identity.MajorMinorRevision = '0.9'

    #--------------------------------------------------------------------------#
    # run the server you want
    #--------------------------------------------------------------------------#
    time = 1 # 5 seconds delay
    loop = LoopingCall(f=modbus_master_update, a=(module, properties, context))
    loop.start(time, now=False) # initially delay by time
    StartTcpServer(context, identity=identity, address=("0.0.0.0", \
                   properties['port_out']))
def main():
	
	store = ModbusSlaveContext(
		di = ModbusSequentialDataBlock(0, [0]*100),
		co = ModbusSequentialDataBlock(0, [0]*100),
		hr = ModbusSequentialDataBlock(0, [0]*100),
		ir = ModbusSequentialDataBlock(0, [0]*100))
	context = ModbusServerContext(slaves=store, single=True)
	identity = ModbusDeviceIdentification()
	identity.VendorName  = 'pymodbus'
	identity.ProductCode = 'PM'
	identity.VendorUrl   = 'http://github.com/simplyautomationized'
	identity.ProductName = 'pymodbus Server'
	identity.ModelName   = 'pymodbus Server'
	identity.MajorMinorRevision = '1.0'
	time = 5 # 5 seconds delaytime = 5 # 5 seconds delay
	writer = LoopingCall(read_context,a=(context,))
	loop = LoopingCall(updating_writer, a=(context,))
	loop.start(.5) # initially delay by time
	writer.start(.1)
	StartTcpServer(context, identity=identity)#, address=("localhost", 502))
	#cleanup async tasks
	temp.setEnabled(False)
	loop.stop()
	writer.stop()
	GPIO.cleanup()
Beispiel #3
0
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/bashwork/pymodbus/'
    identity.ProductName = 'pymodbus Server'
    identity.ModelName = 'pymodbus Server'
    identity.MajorMinorRevision = '2.2.0'
    
    # ----------------------------------------------------------------------- # 
    # 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))
Beispiel #4
0
def ServerThread(e):
	global server
	# Configure the service logging
	#import logging
	#logging.basicConfig()
	#log = logging.getLogger()
	#log.setLevel(logging.DEBUG)

	# 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/bashwork/pymodbus/'
	identity.ProductName = 'Pymodbus Server'
	identity.ModelName   = 'Pymodbus Server'
	identity.MajorMinorRevision = '1.0'


	# Run the server 
	# StartTcpServer(context, identity=identity, address=(args.ip, 502))
	server = ModbusTcpServer(context, identity=identity, address=(ip, 502))
	print 'Server started'
	server.serve_forever(0.1)
	print 'Server stopped'
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/bashwork/pymodbus/'
    identity.ProductName = 'pymodbus Server'
    identity.ModelName = 'pymodbus Server'
    identity.MajorMinorRevision = '2.2.0'

    # ----------------------------------------------------------------------- #
    # 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))
Beispiel #6
0
def run_custom_db_server():
    # ----------------------------------------------------------------------- # 
    # initialize your data store
    # ----------------------------------------------------------------------- # 
    block  = CustomDataBlock([0]*100)
    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/bashwork/pymodbus/'
    identity.ProductName = 'pymodbus Server'
    identity.ModelName = 'pymodbus Server'
    identity.MajorMinorRevision = '2.2.0'

    # ----------------------------------------------------------------------- #
    # run the server you want
    # ----------------------------------------------------------------------- #

    # p = Process(target=device_writer, args=(queue,))
    # p.start()
    StartTcpServer(context, identity=identity, address=("localhost", 5020))
Beispiel #7
0
def identity_factory():
    identity = ModbusDeviceIdentification()
    identity.VendorName  = 'pymodbus'
    identity.ProductCode = 'PM'
    identity.VendorUrl   = 'http://github.com/andreadanzi/pymodbus/'
    identity.ProductName = 'pymodbus Pump Server'
    identity.ModelName   = 'pymodbus Pump Server'
    identity.MajorMinorRevision = '1.0'
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 = '1.5'

    # ----------------------------------------------------------------------- #
    # 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_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))
Beispiel #10
0
    def __init__(self, address, port = MODBUS_PORT):
        store = ModbusSlaveContext(
            di = ModbusSequentialDataBlock(0, [0]*100),
            co = ModbusSequentialDataBlock(0, [0]*100),
            hr = ModbusSequentialDataBlock(0, [0]*100),
            ir = ModbusSequentialDataBlock(0, [0]*100))
        
        self.context = ModbusServerContext(slaves=store, single=True)
        
        identity = ModbusDeviceIdentification()
        identity.VendorName         = 'MockPLCs'
        identity.ProductCode        = 'MP'
        identity.VendorUrl          = 'http://github.com/bashwork/pymodbus/'
        identity.ProductName        = 'MockPLC 3000'
        identity.ModelName          = 'MockPLC Ultimate'
        identity.MajorMinorRevision = '1.0'

        ModbusServerFactory.__init__(self, self.context, ModbusSocketFramer, identity)
Beispiel #11
0
def main():
    # initialize the four register types
    store = ModbusSlaveContext(
        di = ModbusSequentialDataBlock(0, [0]*100),
        co = ModbusSequentialDataBlock(0, [0]*100),
        hr = ModbusSequentialDataBlock(0, [0]*100),
        ir = ModbusSequentialDataBlock(0, [0]*100))
    context = ModbusServerContext(slaves=store, single=True)
    
    identity = ModbusDeviceIdentification()
    identity.VendorName  = 'SPARSA'
    identity.ProductCode = 'SP'
    identity.VendorUrl   = 'http://gentoocloud.com/bitchimabus'
    identity.ProductName = 'SPARSA Temperature Sensor'
    identity.ModelName   = 'SP_1337'
    identity.MajorMinorRevision = '1.0'
    pi.start()
    time = 5 # 5 seconds delaytime = 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=(args.address, 502))
Beispiel #12
0
def main():
    logging.basicConfig()
    #server_log   = logging.getLogger("pymodbus.server")
    #protocol_log = logging.getLogger("pymodbus.protocol")

    """ Server launcher """
    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option("-D", "--debug",
                    help="Turn on to enable tracing",
                    action="store_true", dest="debug", default=False)
    (opt, arg) = parser.parse_args()

    # enable debugging information
    if opt.debug:
        try:
            _logger.setLevel(logging.DEBUG)
        except Exception:
            print "Logging is not supported on this system"

    # Create store context
    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://unipi.technology'
    identity.ProductName = 'Pymodbus Server on IOLoop'
    identity.ModelName   = 'Pymodbus Server'
    identity.MajorMinorRevision = '1.0'

    StartTcpServer(context, identity=identity, address=("localhost", 5020)) 
Beispiel #13
0
            pass
        except Exception, E:
            logger.debug(str(E))
            pass

    def status_callback(self, device):
        try:
            device._modbus_handle.sync(device, self.bits, self.regs)
        except AttributeError:
            pass
        except Exception,e :
            #print str(e)
            pass


## small version of Modbus map, limited to Gpio devices
class UnipiContextGpio(UnipiContext):

    devicemap = { # count coil-pos reg-pos  alt-reg-pos 
    'ao'    : (AoHandle   (1,      0,      1),),
    'input' : (InputHandle(14,     1,      2,      3),),
    }

identity = ModbusDeviceIdentification()
identity.VendorName  = 'Unipi Technology'
identity.ProductCode = 'Evok'
identity.VendorUrl   = 'http://unipi.technology'
identity.ProductName = 'Evok Modbus/TCP Server on Tornado'
identity.ModelName   = 'Evok Modbus'
identity.MajorMinorRevision = '1.1'
def run_async_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 from 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 you may use a seperate 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(
        hr=ModbusSequentialDataBlock(2000, [0]*2100))
    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/bashwork/pymodbus/'
    identity.ProductName = 'Pymodbus Server'
    identity.ModelName = 'Pymodbus Server'
    identity.MajorMinorRevision = '2.2.0'
    
    # ----------------------------------------------------------------------- # 
    # run the server you want
    # ----------------------------------------------------------------------- # 

    # TCP Server

    StartTcpServer(context, identity=identity, address=("", 502), #https://stackoverflow.com/questions/47264617/pymodbus-server-port-502-not-open-starttcpserver
                   custom_functions=[CustomModbusRequest])
Beispiel #15
0
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 = '1.0'

#---------------------------------------------------------------------------#
# run the server you want
#---------------------------------------------------------------------------# 
# Tcp:
# StartTcpServer(context, identity=identity, address=("localhost", 5020))

# Udp:
#StartUdpServer(context, identity=identity, address=("localhost", 502))

# Ascii:
#StartSerialServer(context, identity=identity, port='/dev/pts/3', timeout=1)
Beispiel #16
0
from pymodbus.server.sync import StartTcpServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

import logging

logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

identity = ModbusDeviceIdentification()
identity.VendorName = 'Joac-Automation'
identity.ProductCode = 'PM'
identity.VendorUrl = 'http://github.com/joac/ArakurWW/'
identity.ProductName = 'Servidor Test Arakur'
identity.ModelName = 'Servidor Test Arakur'
identity.MajorMinorRevision = '0.1'

marcas = ModbusSequentialDataBlock(0, [0] * 34)
registros = ModbusSequentialDataBlock(0, [0] * 34)



store = ModbusSlaveContext(di = marcas, co= marcas, hr = registros, ir =registros)

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


StartTcpServer(context, identity=identity, address=("localhost", 5020))
Beispiel #17
0
            hr = hr,
            ir = ir)
        context = ModbusServerContext(slaves=store, single=True)
        
        return context  


#---------------------------------------------------------------------------# 
# initialize the server information
#---------------------------------------------------------------------------# 
# If you don't set this or any fields, they are defaulted to empty strings.
#---------------------------------------------------------------------------# 
identity = ModbusDeviceIdentification()
identity.VendorName  = 'VOLTTRON'
identity.ProductCode = 'VT'
identity.VendorUrl   = 'http://github.com/VOLTTRON/volttron'
identity.ProductName = 'VOLTTRON Modbus Test Device'
identity.ModelName   = 'VOLTTRON Modbus Test Device'
identity.MajorMinorRevision = '1.0'

abstraction = DeviceAbstraction(args.config)

#Create the deamon as soon as we've loaded the device configuration.
if not args.no_daemon:
    createDaemon()
    
context = abstraction.get_server_context()

#---------------------------------------------------------------------------# 
# run the server you want
#---------------------------------------------------------------------------# 
Beispiel #18
0
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 = '2.2.0'

    # ----------------------------------------------------------------------- #
    # run the server you want
    # ----------------------------------------------------------------------- #
    # Tcp:
    # StartTcpServer(context, identity=identity, address=("localhost", 5020))

    # TCP with different framer
    # StartTcpServer(context, identity=identity,
    #                framer=ModbusRtuFramer, address=("0.0.0.0", 5020))

    # Udp:
    # StartUdpServer(context, identity=identity, address=("0.0.0.0", 5020))

    # Ascii:
    # StartSerialServer(context, identity=identity,
    #                    port='/dev/ttyp0', timeout=1)

    # RTU:
    StartSerialServer(context,
                      framer=ModbusRtuFramer,
                      identity=identity,
                      port='/dev/ttyUSB0',
                      timeout=.005,
                      baudrate=115200)
Beispiel #19
0
#         0x03: ModbusSlaveContext(...),
#     }
#     context = ModbusServerContext(slaves=slaves, single=False)
#---------------------------------------------------------------------------#
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/bashwork/pymodbus/'
identity.ProductName = 'Pymodbus Server'
identity.ModelName = 'Pymodbus Server'
identity.MajorMinorRevision = '1.0'

#---------------------------------------------------------------------------#
# run the server you want
#---------------------------------------------------------------------------#
StartTcpServer(context, identity=identity, address=("localhost", 5020))
#StartUdpServer(context, identity=identity, address=("localhost", 502))
#StartSerialServer(context, identity=identity, port='/dev/pts/3', framer=ModbusRtuFramer)
#StartSerialServer(context, identity=identity, port='/dev/pts/3', framer=ModbusAsciiFramer)
Beispiel #20
0
        'ProductCode': "SAS TSXETY4103",
        'VendorUrl': "",
        'ProductName': "",
        'ModelName': "Model",
        'MajorMinorRevision': "1.0"
    },
}

#print("Liste des signature : ")
#-affichagesignature(dico)
#i = demandeobligatoire("Quelle signature voulez vous utiliser ?","int")

identity = ModbusDeviceIdentification()
identity.VendorName = dico[sys.argv[1]]['VendorName']
identity.ProductCode = dico[sys.argv[1]]['ProductCode']
identity.VendorUrl = dico[sys.argv[1]]['VendorUrl']
identity.ProductName = dico[sys.argv[1]]['ProductName']
identity.ModelName = dico[sys.argv[1]]['ModelName']
identity.MajorMinorRevision = dico[sys.argv[1]]['MajorMinorRevision']

#---------------------------------------------------------------------------#
# run the server you want
#---------------------------------------------------------------------------#
# Tcp:
print("=== [START] ====")
log.info("Server start")
StartTcpServer(context, identity=identity, address=("0.0.0.0", 502))

# Udp:
#StartUdpServer(context, identity=identity, address=("localhost", 502))
Beispiel #21
0
            time.sleep(1)


# Modbus stuff
store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [0] * 100),
                           co=ModbusSequentialDataBlock(0, [0] * 100),
                           hr=ModbusSequentialDataBlock(0, [0] * 100),
                           ir=ModbusSequentialDataBlock(0, [0] * 100))

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

# Modbus PLC server information
identity = ModbusDeviceIdentification()
identity.VendorName = 'Simmons Oil Refining Platform'
identity.ProductCode = 'SORP'
identity.VendorUrl = 'http://simmons.com/markets/oil-gas/pages/refining-industry.html'
identity.ProductName = 'SORP 3850'
identity.ModelName = 'Simmons ORP 3850'
identity.MajorMinorRevision = '2.09.01'

# Port the world will listen on
MODBUS_SERVER_PORT = 5020
# MODBUS_SERVER_ADDR = "127.0.0.1"

# PLC Register values for various control functions
PLC_FEED_PUMP = 0x01
PLC_TANK_LEVEL = 0x02
PLC_OUTLET_VALVE = 0x03
PLC_SEP_VALVE = 0x04
PLC_OIL_SPILL = 0x06
PLC_OIL_PROCESSED = 0x07
Beispiel #22
0
from pymodbus.server.sync import StartTcpServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
import logging

if __name__ == "__main__":

    logging.basicConfig()
    log = logging.getLogger()
    log.setLevel(logging.DEBUG)

    identify = ModbusDeviceIdentification()
    identify.VendorName = 'P4A'
    identify.ProductCode = 'P4AMBS'
    identify.VendorUrl = 'http://performanceforassets.com'
    identify.ProductName = 'P4AModbusServer'
    identify.MajorMinorRevision = '1.0'

    store = ModbusSlaveContext(
        di=ModbusSequentialDataBlock(0, [0] * 0xff),
        co=ModbusSequentialDataBlock(0, [0] * 0xff),
        hr=ModbusSequentialDataBlock(
            0, [0] * 0xff),  #holding register, seems to be 16 bits by default
        ir=ModbusSequentialDataBlock(0, [0] * 0xff))
    context = ModbusServerContext(slaves=store, single=True)
    StartTcpServer(
        context, identity=identify,
        address=("localhost",
                 5020))  #put lan ip if you want outside computer to access it
Beispiel #23
0
import requests
import json
import os
uid = None
# Data Store for PLC Devices hr is used for Reg Read and Reg Write and is the only register interaction
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)

# Data Store for PLC Devices hr is used for Reg Read and Reg Write and is the only register interaction
identity = ModbusDeviceIdentification()
identity.VendorName = 'Facility Sensor System'
identity.ProductCode = 'FSS'
identity.VendorUrl = 'http://www.wehaveyourback.com'
identity.ProductName = 'PLC Sensor Server'
identity.ModelName = 'Sensor Server 5000'
identity.MajorMinorRevision = '3.a1'


# Class: PLC Server Thread
# Description: HMI Machines maintain connection between the PLC device and the Historian. The PLC Thread maintains three
# threads one for the Server itself the interacts directly with the PLC devices. The second is the polling of sensor
# systems and update the database. Lastly the actuator which polls and communicates with the the PLC actuators and
# reflects the changes to the database and sensors.
class PLCThread(threading.Thread):
    # Method: Initializer
    # Description: Initializer for PLC Thread Object to help create the connection between the PLC devices and
    # postgres DB
    # Arguments: address: Address of the System to be used to host the server
store = ModbusSlaveContext(
    di = ModbusSequentialDataBlock(0, [False]*100),
    co = ModbusSequentialDataBlock(0, [False]*100),
    hr = ModbusSequentialDataBlock(0, [0]*100),
    ir = ModbusSequentialDataBlock(0, [0]*100))
context = ModbusServerContext(slaves=store, single=True)

#---------------------------------------------------------------------------# 
# initialize the server information
#---------------------------------------------------------------------------# 

identity = ModbusDeviceIdentification()
identity.VendorName = 'ZXL'
identity.ProductCode = 'PLC'
identity.VendorUrl = 'https://github.com/zxlin/Modbus-PLC-Simulator'
identity.ProductName = 'PLC-Sim'
identity.ModelName = 'Modbus-Server'
identity.MajorMinorRevision = '1.0'


#---------------------------------------------------------------------------# 
# Start running the server
#---------------------------------------------------------------------------#
time = 3
loop = LoopingCall(f=logToArcSight, a=(context,))
loop1 = LoopingCall(f=updating_writer, a=(context,))
loop.start(30, now=True)
loop1.start(time, now=True)
StartTcpServer(context, identity=identity, address=(server_address, server_port))
def run_updating_server():
    # ----------------------------------------------------------------------- #
    # initialize your data store
    # ----------------------------------------------------------------------- #

    parser = argparse.ArgumentParser()
    parser.add_argument('-server_ip',
                        action='store',
                        dest='server_ip',
                        type=str,
                        help='Input the ip address of modbus server')
    parser.add_argument('-server_port',
                        action='store',
                        dest='server_port',
                        type=int,
                        help='Input the port of modbus server')
    arg = parser.parse_args()

    # 模拟佳环高频电源modbus-tcp的开关量输出
    list_co_context = []
    for i in range(200):  #0000000-000157 一共158点

        if i % 2 == 0:
            list_co_context.append(0)
        else:
            list_co_context.append(1)
    # 模拟佳环高频电源modbus-tcp的模拟量输入
    list_ir_context = []
    for i in range(10):
        list_ir_context.append(i + 0)

    # 模拟佳环高频电源modbus-tcp的模拟量输出
    list_hr_context = []
    for i in range(200):  #400011-400164 一共154点
        list_hr_context.append(i + 0)

    #store = ModbusSlaveContext(
    #di = ModbusSequentialDataBlock(0, [11]*100),
    #co = ModbusSequentialDataBlock(0, [12]*100),
    #hr = ModbusSequentialDataBlock(0, [13]*100),
    #ir = ModbusSequentialDataBlock(0, [14]*100))

    store = ModbusSlaveContext(
        di=ModbusSequentialDataBlock(0, [0] * 100),
        co=ModbusSequentialDataBlock(0, list_co_context),
        hr=ModbusSequentialDataBlock(0, list_hr_context),
        ir=ModbusSequentialDataBlock(0, list_ir_context))

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

    # ----------------------------------------------------------------------- #
    # initialize the server information
    # ----------------------------------------------------------------------- #
    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.0'

    # ----------------------------------------------------------------------- #
    # run the server you want
    # ----------------------------------------------------------------------- #
    time = 2  # 5 seconds delay
    loop = LoopingCall(f=updating_writer, a=(context, ))
    loop.start(time, now=False)  # initially delay by time
    #StartTcpServer(context, identity=identity, address=("192.168.168.100", 5021))
    StartTcpServer(context,
                   identity=identity,
                   address=(arg.server_ip, arg.server_port))
Beispiel #26
0
def run_server(modbus_type, port):
    # ----------------------------------------------------------------------- #
    # 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 you may use a seperate 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)
    # ----------------------------------------------------------------------- #

    #block = ModbusSequentialDataBlock(0x00, [16]*0xff)
    coils_block = ModbusSparseDataBlock({1: 0, 2: 1, 3: 0, 4: 1})

    registers_block = ModbusSparseDataBlock({
        # this block is to test 32bits
        1: 0xC28F,  # PDU0 - BE
        2: 0xC20D,
        3: 0x8FC2,  # PDU2 - MBE
        4: 0x0DC2,
        5: 0xC20D,  # PDU4 - MLE
        6: 0xC28F,
        7: 0x0DC2,  # PDU6 - LE
        8: 0x8FC2,
        #
        9: 0xC28F,  # PDU8 - same as (PDU0 - BE)
        10: 0xC20D,
        11: 0xC28F,  # PDU0 - same as (PDU0 - BE)
        12: 0xC20D,

        # test int32
        13: 0xFFFF,  # PDU12
        14: 0xFDCE,

        # this block is to test 64bits
        # BE
        15: 0xBFBF,  # PDU14
        16: 0x9A6B,
        17: 0x50B0,
        18: 0xF27C,

        # LE
        19: 0x7CF2,  # PDU18
        20: 0xB050,
        21: 0x6B9A,
        22: 0xBFBF,

        # MLE
        23: 0xF27C,  # PDU22
        24: 0x50B0,
        25: 0x9A6B,
        26: 0xBFBF,

        # MBE
        27: 0xBFBF,  # PDU26
        28: 0x6B9A,
        29: 0xB050,
        30: 0x7CF2
    })
    store = ModbusSlaveContext(di=coils_block,
                               co=coils_block,
                               hr=registers_block,
                               ir=registers_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 = '1.5'

    # ----------------------------------------------------------------------- #
    # run the server you want
    # ----------------------------------------------------------------------- #
    # Tcp:
    if (modbus_type == 'TCP'):
        StartTcpServer(context, identity=identity, address=("0.0.0.0", port))
    elif (modbus_type == 'TCP_RTU'):
        # TCP with different framer
        StartTcpServer(context,
                       identity=identity,
                       framer=ModbusRtuFramer,
                       address=("0.0.0.0", port))
Beispiel #27
0
    def _start_rtu_server(self, framer=ModbusRtuFramer):
        # @req an open and existing /tmp/pts0 is required
        #---------------------------------------------------------------------------#
        # initialize your data store
        #---------------------------------------------------------------------------#
        # The datastores only respond to the addresses that they are initialized to.
        # Therefore, if you initialize a DataBlock to addresses from 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 you may use a seperate 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, [True] * 8),  # discrete inputs
            co=ModbusSequentialDataBlock(0, [False] * 8),  # coils
            hr=ModbusSequentialDataBlock(0, [0] * 8),  # holding regs
            ir=ModbusSequentialDataBlock(0, list(range(8))),  # input regs
            zero_mode=True)  # request(0-7) will map to the address (0-7)
        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.0'

        #---------------------------------------------------------------------------#
        # run the server you want
        #---------------------------------------------------------------------------#
        #StartTcpServer(context, identity=identity, address=("localhost", 5020))
        #StartUdpServer(context, identity=identity, address=("localhost", 502))
        StartSerialServer(context,
                          identity=identity,
                          port=self.serialPort,
                          baudrate=19200,
                          framer=framer)
Beispiel #28
0
         'VendorUrl':"", 
         'ProductName':"", 
         'ModelName':"Model", 
         'MajorMinorRevision':"1.0"
        },
}

#print("Liste des signature : ")
#-affichagesignature(dico)
#i = demandeobligatoire("Quelle signature voulez vous utiliser ?","int")
i = 0

identity = ModbusDeviceIdentification()
identity.VendorName  = dico[i]['VendorName']
identity.ProductCode = dico[i]['ProductCode']
identity.VendorUrl   = dico[i]['VendorUrl']
identity.ProductName = dico[i]['ProductName']
identity.ModelName   = dico[i]['ModelName']
identity.MajorMinorRevision = dico[i]['MajorMinorRevision']

#---------------------------------------------------------------------------#
# run the server you want
#---------------------------------------------------------------------------# 
# Tcp:
log.info("TcpServer START")
StartTcpServer(context, identity=identity, address=("localhost", 502))
log.info("[ %s ] TcpServer STOP", time.asctime())

# Udp:
#StartUdpServer(context, identity=identity, address=("localhost", 502))
Beispiel #29
0
logging.basicConfig()
log = logging.getLogger("OpcToModbus")
log.setLevel(logging.INFO)  # You may change this for production depoy

# Host address of the OPC Server
opc_host = "opc.tcp://localhost:4840/freeopcua/server/"

# Host adress for the Modbus Server
modbus_host = "localhost"
modbus_port = 5020

# Modbus server information
identity = ModbusDeviceIdentification()
identity.VendorName = 'Fuinha11'
identity.ProductCode = 'POTM'
identity.VendorUrl = 'https://github.com/Fuinha11'
identity.ProductName = 'OPC to Modbus'
identity.ModelName = 'O2M0.1'
identity.MajorMinorRevision = '0.0.1'

# Time between updates in sec
update_inteval = 1.5

# ----------------------------------------------------------------------- #
# End of Configuration
# ----------------------------------------------------------------------- #

opc_client: Client


def initiate_client():
#---------------------------------------------------------------------------# 
# initialize 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 = 'ZXL'
identity.ProductCode = 'PLC'
identity.VendorUrl = 'https://github.com/zxlin/Modbus-PLC-Simulator'
identity.ProductName = 'PLC-Sim'
identity.ModelName = 'Modbus-Server'
identity.MajorMinorRevision = '1.0'

#---------------------------------------------------------------------------# 
# Start running the server
#---------------------------------------------------------------------------#
# time = 5
# loop = LoopingCall(f=updating_writer, a=(context,))
# loop.start(time, now=False)
StartTcpServer(context, identity=identity, address=(server_address, server_port))
Beispiel #31
0
def run_updating_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 from 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 you may use a seperate 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)
    # '''
    # __fx_mapper = {2: 'd', 4: 'i'}
    # __fx_mapper.update([(i, 'h') for i in [3, 6, 16, 22, 23]])
    # __fx_mapper.update([(i, 'c') for i in [1, 5, 15]])
    # '''
    # ----------------------------------------------------------------------- #
    store = ModbusSlaveContext(
        # di=ModbusSequentialDataBlock(1000, [1]*287),
        co=ModbusSequentialDataBlock(1000, [0] * 287),
        # 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/bashwork/pymodbus/'
    identity.ProductName = 'Pymodbus Server'
    identity.ModelName = 'Pymodbus Server'
    identity.MajorMinorRevision = '1.5'

    # ----------------------------------------------------------------------- #
    # run the server you want
    # ----------------------------------------------------------------------- #

    # TCP Serverq

    # StartXMLClient
    # StartTcpServer
    time = 3  # 1 seconds delay
    modbus_addr = "0.0.0.0", 5020

    loop = LoopingCall(f=updating_writer, a=(context, ))
    loop.start(time, now=False)  # initially delay by time

    StartTcpServer(context, identity=identity, address=modbus_addr)
Beispiel #32
0
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)
    if reactor.running:
        reactor.callFromThread(reactor.stop)

store = ModbusSlaveContext(
    di = ModbusSequentialDataBlock(0, [0]*100),
    co = ModbusSequentialDataBlock(0, [0]*100),
    hr = ModbusSequentialDataBlock(0, [0]*100),
    ir = ModbusSequentialDataBlock(0, [0]*100))

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

# Modbus PLC server information
identity = ModbusDeviceIdentification()
identity.VendorName  = 'Simmons Oil Refining Platform'
identity.ProductCode = 'SORP'
identity.VendorUrl   = 'http://simmons.com/markets/oil-gas/pages/refining-industry.html'
identity.ProductName = 'SORP 3850'
identity.ModelName   = 'Simmons ORP 3850'
identity.MajorMinorRevision = '2.09.01'

def startModbusServer():
    # Run a modbus server on specified address and modbus port (5020)
    StartTcpServer(context, identity=identity, address=(args.server_addr, MODBUS_SERVER_PORT))

def main():
    reactor.callInThread(run_world)
    startModbusServer()

if __name__ == '__main__':
    sys.exit(main())
Beispiel #34
0
def run_updating_server(config_in, config_section=None):
    """ This function updates all the registers of each type contained in
    the config file to their specified initial value.

    :param config_in: YAML config file containing all settings (see example)
    :param config_section: section settings are under
    :returns: Nothing
    """

    # read config file
    if (config_section==None):
        modbus_section = 'server'


    with open(config_in) as f:
        # use safe_load instead load
        modbusConfig = yaml.safe_load(f)

    PORT = modbusConfig[modbus_section]['port']
    DEFINED_BLOCK = modbusConfig[modbus_section]['use_block_size']
    slave_id = modbusConfig[modbus_section]['slave_id']
    update_time = modbusConfig[modbus_section]['update_time']

    random_range = modbusConfig[modbus_section]['random_range']
    ramp_slope = modbusConfig[modbus_section]['ramp_slope']

    holding_float_dict = modbusConfig[modbus_section]['float_holding']
    holding_int32_dict = modbusConfig[modbus_section]['int32_holding']
    holding_int16_dict = modbusConfig[modbus_section]['int16_holding']

    input_float_dict = modbusConfig[modbus_section]['float_input']
    input_int32_dict = modbusConfig[modbus_section]['int32_input']
    input_int16_dict = modbusConfig[modbus_section]['int16_input']

    coil_dict = modbusConfig[modbus_section]['coil_registers']
    discrete_dict = modbusConfig[modbus_section]['discrete_registers']

    if (DEFINED_BLOCK == True):
        # User has defined a custom block and offset, read the settings
        # from the config file.

        print("block size is user defined")
        coil_block_size = modbusConfig[modbus_section]['coil_block_size']
        coil_block_offset = modbusConfig[modbus_section]['coil_block_offset']

        discrete_block_size = modbusConfig[modbus_section]['discrete_block_size']
        discrete_block_offset = modbusConfig[modbus_section]['discrete_block_offset']

        holding_block_size = modbusConfig[modbus_section]['holding_block_size']
        holding_block_offset = modbusConfig[modbus_section]['holding_block_offset']

        input_block_size = modbusConfig[modbus_section]['holding_block_size']
        input_block_offset = modbusConfig[modbus_section]['holding_block_offset']
    else:
        print("use auto calulcator")
        # Calculate size needed for each register type
        holding_block_size = len(holding_float_dict)*2
        holding_block_size += len(holding_int32_dict)*2
        holding_block_size += len(holding_int16_dict)*1

        input_block_size = len(input_float_dict)*2
        input_block_size += len(input_int32_dict)*2
        input_block_size += len(input_int16_dict)*1

        discrete_block_size = len(discrete_dict)
        coil_block_size = len(coil_dict)

        coil_block_offset = 0
        discrete_block_offset = 0
        holding_block_offset = 0
        input_block_offset = 0

    # ----------------------------------------------------------------------- #
    # initialize data store according to config file
    # ----------------------------------------------------------------------- #
    store = ModbusSlaveContext(
        di=ModbusSequentialDataBlock(discrete_block_offset, [0]*discrete_block_size),
        co=ModbusSequentialDataBlock(coil_block_offset, [0]*coil_block_size),
        hr=ModbusSequentialDataBlock(holding_block_offset, [0]*holding_block_size),
        ir=ModbusSequentialDataBlock(input_block_offset, [0]*input_block_size))
    context = ModbusServerContext(slaves=store, single=True)


    # ----------------------------------------------------------------------- #
    # initialize the server information
    # ----------------------------------------------------------------------- #
    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.0'

    #slave_id = 0x00
    # Set all registers to their initial value as specified in config file
    initialize_registers(context,slave_id,holding_float_dict,holding_int32_dict,
        holding_int16_dict,input_float_dict,input_int32_dict,input_int16_dict,
        coil_dict, discrete_dict)
    # Set updating time and call updating writer inside a loop accorind to interval
    # time
    time = update_time
    loop = LoopingCall(f=updating_writer, context=(context),slave_id=(slave_id),
        holding_float_dict=(holding_float_dict),
        holding_int32_dict=(holding_int32_dict),
        holding_int16_dict=(holding_int16_dict),
        input_float_dict=(input_float_dict),
        input_int32_dict=(input_int32_dict),
        input_int16_dict=(input_int16_dict),
        coil_dict=(coil_dict),
        discrete_dict=(discrete_dict),
        random_range=(random_range),
        ramp_slope=(ramp_slope))
    loop.start(time, now=False) # initially delay by time


    # Setting address to 127.0.0.1 allows only the local machine to access the
    # Server. Changing to 0.0.0.0 allows for other hosts to connect.
    StartTcpServer(context, identity=identity, address=("0.0.0.0", 5020))
###############################################################################
# Modbus Datastore Configuration
###############################################################################

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 = 'ITI'
identity.ProductCode = 'PM'
identity.VendorUrl = 'code.iti.illinois.edu'
identity.ProductName = 'Server Instance'
identity.ModelName = 'ITI Test'
identity.MajorMinorRevision = '1.0'

###############################################################################
# Functions
###############################################################################



def validateIface(iface):
    if not (iface in netifaces.interfaces()):
        print iface + " is not a valid interface"
        exit()
Beispiel #36
0
    # ------------------------------------------------------------
    from pymodbus.server.async import ModbusServerFactory
    from pymodbus.constants import Defaults
    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/bashwork/pymodbus/'
    identity.ProductName = 'Pymodbus Server'
    identity.ModelName   = 'Pymodbus Server'
    identity.MajorMinorRevision = '1.0'

    # ------------------------------------------------------------
    # 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)

    # ------------------------------------------------------------
Beispiel #37
0
#---------------------------------------------------------------------------#
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 = '1.0'

#---------------------------------------------------------------------------#
# run the server you want
#---------------------------------------------------------------------------#
# Tcp:
StartTcpServer(context, identity=identity, address=("localhost", 502))

# Udp:
#StartUdpServer(context, identity=identity, address=("localhost", 502))

# Ascii:
#StartSerialServer(context, identity=identity, port='/dev/pts/3', timeout=1)
Beispiel #38
0
def run_async_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 from 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 you may use a seperate 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, [18] * 3)
        #ir=ModbusSequentialDataBlock(0, [17]*100))
        #store.register(CustomModbusRequest.function_code, 'cm',
        #ModbusSequentialDataBlock(0, [17] * 100)
    )
    context = ModbusServerContext(slaves=store, single=True)

    # DI: functie 1; coil status (Modbus Doctor)?
    # CO: Input status? COIL?
    # HR: Holding Register
    # IR: Input Register

    # What are we doing here: set address value 0 (1 in Modbus Docter?)
    # Holding Register starts at 40000. So, address 400001.
    # 30000 is for Input Register.
    #
    # Examples include setting 100 * 17 in a list. These are 100
    # registers. On address 0, (1, 40001) there are 100 register
    # values.
    #
    # Register 'should' start at index 1 (40001), so example:
    # hr=ModbusSequentialDataBlock(0, [18]*2) writes 18 at the 40001 position (and 40000?)
    #
    # Example write by Modbus Doctor
    # Green little balls: bits (yes/no)
    # Purple little balls: value of the entire register (16 bits)
    #
    # The green ones affect the values in the entire register
    #
    # Bit 0: Ledstrip On/Off (40001.0)
    # Bit 1: Ledstrip fixed color (40001.1)
    #   If bit 1 is set, read the following addresses
    #   40002: R; 40003: G; 40004: B;
    #   So, reading continuously from the 40002, 3, 4;
    #   Update the values for RGB 'in the background'
    #   Update the ledstrip when values change
    # Bit 2: Activate rainbow (40001.2)
    # Bit 3: Activate color mix / strandtest (40001.3)
    # 40005: number of leds to use;
    #   Only read at the start of ledstrip initialization
    # 40006: brightness to set
    #   Only read at the start of ledstrip initialization
    # 40007: LED pin (digital pin)
    #   Only read at the start of ledstrip initialization
    # Add handling of UNITs (devices, device addresses)
    #   See https://github.com/riptideio/pymodbus/blob/master/examples/common/asynchronous_server.py#L77
    #   Idea is to run 'multiple instances' of the ledstrip for different
    #   contexts / hardware. The logic is exactly the same, only the
    #   'database' of values stores is different.
    # 40008: Which program should be active
    #   Value 1, 2, 3, (etc)
    #   1: fixed color, 2: rainbow, 3: color mix
    #
    # Look into CustomModbusRequest for handling data changes
    #   See ModbusTcpServer.StartTCPServer logging functionality
    #   Also see request.execute; https://github.com/riptideio/pymodbus/blob/13de8ab0a840d04b41cf53b9aaa98875d96ac5ec/pymodbus/server/async.py#L58
    #   Framer, decoder, custom_functions, custom messages
    #   https://github.com/riptideio/pymodbus/blob/2ef91e9e565b10fc9abc0840c87cf4a29f3d9bbf/pymodbus/server/asynchronous.py#L233
    #
    # Proposed solution: create LedstripRequest, extending ModbusRequest
    # Override the default function code (3), register the LedstripRequest,
    # override the execute funtion to react to specific data changes on specific
    # addresses, store data from the changed data from registers in local variables
    # update the ledstrip code to lookup values from local variables and react to
    # changes
    #
    # Bit values are on/off; react to on/off states. Toggle function.
    # No function active: ledstip should shutdown
    #

    # ----------------------------------------------------------------------- #
    # initialize the server information
    # ----------------------------------------------------------------------- #
    # If you don't set this or any fields, they are defaulted to empty strings.
    # ----------------------------------------------------------------------- #
    identity = ModbusDeviceIdentification()
    identity.VendorName = 'hslatman'
    identity.ProductCode = 'MLS'
    identity.VendorUrl = 'https://github.com/hslatman/ledstrip'
    identity.ProductName = 'ModLed Server'
    identity.ModelName = 'ModLed X'
    identity.MajorMinorRevision = '0.1.0'

    # ----------------------------------------------------------------------- #
    # run the server you want
    # ----------------------------------------------------------------------- #

    # TCP Server

    # StartTcpServer(context, identity=identity, address=("0.0.0.0", 502),
    #                custom_functions=[CustomModbusRequest])

    #StartTcpServer(context, identity=identity, address=("0.0.0.0", 502))

    StartTcpServer(context,
                   identity=identity,
                   address=("0.0.0.0", 502),
                   custom_functions=[LedstripControlRequest])
Beispiel #39
0
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 = '2.2.0'

    # ----------------------------------------------------------------------- #
    # run the server you want
    # ----------------------------------------------------------------------- #
    # Tcp:
    StartTcpServer(context, identity=identity, address=("localhost", 5020))
Beispiel #40
0
    # enable debugging information
    if opt.debug:
        try:
            _logger.setLevel(logging.DEBUG)
        except Exception, e:
            print "Logging is not supported on this system"

    # Create store context
    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://unipi.technology'
    identity.ProductName = 'Pymodbus Server on IOLoop'
    identity.ModelName   = 'Pymodbus Server'
    identity.MajorMinorRevision = '1.0'

    StartTcpServer(context, identity=identity, address=("localhost", 5020)) 


if __name__ == '__main__':
    main()

Beispiel #41
0
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

# Create a datastore and populate it with test data
store = ModbusSlaveContext(
    di=ModbusSequentialDataBlock(
        0, [17] *
        100),  # Initialisation des Discrete Inputs (booléens en lecture seule)
    co=ModbusSequentialDataBlock(
        0,
        [17] * 100),  # Initialisation des Coils (booléens en lecture/écriture)
    hr=ModbusSequentialDataBlock(
        0, [17] * 100
    ),  # Initialisation des Holding Register ( nombres entiers en lecture/écriture)
    ir=ModbusSequentialDataBlock(
        0, [17] *
        100))  # Initialisation des Input Registers (entiers en lecture seule)
context = ModbusServerContext(slaves=store, single=True)

# Ces champs sont renvoyés par le serveur au client
identity = ModbusDeviceIdentification()
identity.VendorName = 'PyModbus Inc.'
identity.ProductCode = 'PM'
identity.VendorUrl = 'https://github.com/riptideio/pyModbus'
identity.ProductName = 'Modbus Server'
identity.ModelName = 'PyModbus'
identity.MajorMinorRevision = '1.0'

print("Démarrage du serveur Modbus:")
StartTcpServer(context, identity=identity, address=("0.0.0.0", 502))
Beispiel #42
0
        store = ModbusSlaveContext(di=di, co=co, hr=hr, ir=ir)
        context = ModbusServerContext(slaves=store, single=True)

        return context


#---------------------------------------------------------------------------#
# initialize the server information
#---------------------------------------------------------------------------#
# If you don't set this or any fields, they are defaulted to empty strings.
#---------------------------------------------------------------------------#
identity = ModbusDeviceIdentification()
identity.VendorName = 'VOLTTRON'
identity.ProductCode = 'VT'
identity.VendorUrl = 'http://github.com/VOLTTRON/volttron'
identity.ProductName = 'VOLTTRON Modbus Test Device'
identity.ModelName = 'VOLTTRON Modbus Test Device'
identity.MajorMinorRevision = '1.0'

abstraction = DeviceAbstraction(args.config)

#Create the deamon as soon as we've loaded the device configuration.
if not args.no_daemon:
    createDaemon()

context = abstraction.get_server_context()

#---------------------------------------------------------------------------#
# run the server you want
#---------------------------------------------------------------------------#
Beispiel #43
0
'''
Asynchronous Modbus Server Built in Python using the pyModbus module
'''
# Import the libraries we need
from pymodbus.server.asynchronous import StartTcpServer
#from pymodbus.server.asynchronous import StartTcpServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

# Create a datastore and populate it with test data
store = ModbusSlaveContext(
    di=ModbusSequentialDataBlock(0, [17] * 100),  # Discrete Inputs initializer
    co=ModbusSequentialDataBlock(0, [17] * 100),  # Coils initializer
    hr=ModbusSequentialDataBlock(0,
                                 [17] * 100),  # Holding Register initializer
    ir=ModbusSequentialDataBlock(0, [17] * 100))  # Input Registers initializer
context = ModbusServerContext(slaves=store, single=True)

# Populate the Modbus server information fields, these get returned as
#  response to identity queries
identity = ModbusDeviceIdentification()
identity.VendorName = 'ModbusTagServer'
identity.ProductCode = 'ModbusTagServer'
identity.VendorUrl = 'https://github.com/gilzin'
identity.ProductName = 'ModbusTagServer'
identity.ModelName = 'PyModbus'
identity.MajorMinorRevision = '1.0'
# Start the listening server
print("Starting Modbus server...")
StartTcpServer(context, identity=identity, address=("0.0.0.0", 502))
Beispiel #44
0
def run_async_server():
    """
    The main loop instantiates one or more PyModbus servers mapped to ClearBlade Modbus proxies based on
    IP address and port defined in a ClearBlade platform Collection
    """
    log = None
    virtual_ifs = []
    err_msg = None
    defer_reactor = False

    try:
        parser = get_parser()
        user_options = parser.parse_args()
        local_ip_address = user_options.ip_address
        local_tcp_port = user_options.tcp_port
        net_if = user_options.net_if
        if user_options.log_level == 'DEBUG':
            _debug = True
        else:
            _debug = False
        HEARTBEAT = user_options.heartbeat

        log = headless.get_wrapping_logger(name=ADAPTER_DEVICE_ID, debug=_debug)
        server_log = headless.get_wrapping_logger(name="pymodbus.server", debug=_debug)

        log.info("Initializing ClearBlade System connection")
        cb_system = System(systemKey=user_options.systemKey, systemSecret=user_options.systemSecret, url=user_options.url)
        cb_auth = cb_system.Device(name=user_options.deviceName, key=user_options.deviceKey)
        cb_slave_config = user_options.slaves_collection
        cb_data = user_options.data_collection

        ip_proxies = []
        proxy_ports = []
        ip_address = None
        collection = cb_system.Collection(cb_auth, collectionName=cb_slave_config)
        query = Query()
        query.notEqualTo(COL_PROXY_IP_ADDRESS, '')
        rows = collection.getItems(query)
        for row in rows:
            # TODO: allow for possibility of multiple IPs with same port or same IP with multiple ports
            ip_address = str(row[COL_PROXY_IP_ADDRESS])
            tcp_port = int(row[COL_PROXY_IP_PORT])
            if ip_address not in ip_proxies:
                log.info("Found slave at {} on ClearBlade adapter config".format(ip_address))
                ip_proxies.append(ip_address)
                proxy_ports.append(tcp_port)
            else:
                log.warning("Duplicate proxy IP address {} found in configuration - ignoring".format(ip_address))

        log.debug("Processing {} slaves".format(len(ip_proxies)))
        for i in range(0, len(ip_proxies)):
            log.debug("Getting server context for {}".format(ip_proxies[i]))
            context = ClearBladeModbusProxyServerContext(cb_system=cb_system, cb_auth=cb_auth,
                                                         cb_slaves_config=cb_slave_config, cb_data=cb_data,
                                                         ip_address=ip_proxies[i], log=log)
            # Create IP aliases
            local_ip_address = ip_proxies[i]
            ip_mask = '255.255.255.0'
            local_tcp_port = proxy_ports[i]
            if sys.platform.startswith('win'):
                log.info("I'm on Windows!")
                local_ip_address = 'localhost'
            elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
                virtual_if = '{nif}:{alias}'.format(nif=net_if, alias=i)
                virtual_ifs.append(virtual_if)
                linux_command = "ifconfig {vif} {ip}".format(vif=virtual_if, ip=local_ip_address)
                if ip_mask is not None:
                    linux_command += " netmask {mask}".format(mask=ip_mask)
                log.info("Creating virtual IP address / alias via $ {}".format(linux_command))
                subprocess.call(linux_command, shell=True)

            # Create Server Identification
            identity = ModbusDeviceIdentification()
            identity.VendorName = 'PyModbus'
            identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
            identity.ProductName = 'Inmarsat/ClearBlade Modbus Server Adapter'
            identity.ModelName = ip_proxies[i]
            identity.MajorMinorRevision = '1.0'

            # Setup Modbus TCP Server
            log.info("Starting Modbus TCP server on {}:{}".format(local_ip_address, local_tcp_port))
            modbus_server_args = {
                'context': context,
                'identity': identity,
                'address': (local_ip_address, local_tcp_port),
                # 'console': _debug,
                'defer_reactor_run': True,
            }
            if modbus_server_args['defer_reactor_run']:
                defer_reactor = True
            reactor.callInThread(StartTcpServer, **modbus_server_args)

            if local_ip_address == 'localhost':
                log.info("Windows retricted environment prevents IP alias - running localhost for {}"
                         .format(ip_proxies[i]))
                break

        reactor.callInThread(_heartbeat, log, time.time(), HEARTBEAT)
        if defer_reactor:
            reactor.suggestThreadPoolSize(len(ip_proxies))
            reactor.run()

    except KeyboardInterrupt:
        err_msg = "modbus_server_adapter.py halted by Keyboard Interrupt"
        if log is not None:
            log.info(err_msg)
        else:
            print(err_msg)
        sys.exit("modbus_server_adapter.py halted by Keyboard Interrupt")

    except Exception as e:
        err_msg = "EXCEPTION: {}".format(e)
        if log is not None:
            log.info(err_msg)
        else:
            print(err_msg)
        sys.exit("modbus_server_adapter.py halted by exception {}".format(e))

    finally:
        if defer_reactor and reactor.running:
            reactor.stop()
        for vif in virtual_ifs:
            debug_msg = "Taking down virtual interface {}".format(vif)
            if log is not None:
                log.debug(debug_msg)
            else:
                print(debug_msg)
            linux_command = "ifconfig {} down".format(vif)
            subprocess.call(linux_command, shell=True)
        print("Exiting...")