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)