class ModbusWrapperServer(): def __init__(self,port=1234): """ Creates a Modbus TCP Server object .. note:: The default port for modbus is 502. This modbus server uses port 1234 by default, otherwise superuser rights are required. .. note:: Use "startServer" to start the listener. :param port: Port for the modbus TCP server :type port: int """ # chr = CustomHoldingRegister(ADDRESS_WRITE_START, [16]*100) # cdi = CustomHoldingRegister(ADDRESS_WRITE_START, [16]*100) self.onShutdown=False; self.state_changed = Signal() cco = CustomHoldingRegister(ADDRESS_WRITE_START, [16]*100) self.store = ModbusSlaveContext( di = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [16]*100), co = cco, hr = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [16]*100), ir = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [16]*100)) self.context = ModbusServerContext(slaves=self.store, single=True) self.identity = ModbusDeviceIdentification() self.identity.VendorName = 'Pymodbus' self.identity.ProductCode = 'PM' self.identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' self.identity.ProductName = 'Pymodbus Server' self.identity.ModelName = 'Pymodbus Server' self.identity.MajorMinorRevision = '1.0' self.store.setValues(2,0,[0]*1) self.post = Post(self) framer = ModbusSocketFramer self.server = ModbusTcpServer(self.context, framer, self.identity, address=("0.0.0.0", port)) def startServer(self): """ Non blocking call to start the server """ self.post._startServer() def _startServer(self): print "Modbus server started" self.server.serve_forever() def stopServer(self): """ Closes the server """ self.onShutdown = True self.server.server_close() self.server.shutdown() def waitForCoilOutput(self,address,timeout=2): now = time.time() while not self.onShutdown: values = self.store.getValues(1,address, 1) if values[0] is True: return True else: if timeout > 0 and now + timeout > time.time(): time.sleep(1/50) else: return False def stateChangeListener(self,address): self.post.__stateChangeListener(address) def __stateChangeListener(self,address): old_state = 0; while not self.onShutdown: value = self.store.getValues(1,address, 1)[0] if old_state != value: old_state = value self.state_changed(address,value) #print "state has changed" time.sleep(1/50) def setDigitalInput(self,address,values): if not values is list: values = [values] self.store.setValues(2,address,values) def triggerInput(self,address,timeout=0.5): self.setDigitalInput(address, True) self.post.resetInput(address, timeout) def resetInput(self,address,timeout): time.sleep(timeout) self.setDigitalInput(address, False)