title: pymodbus how to test my serial RTU server over a real serial port
body: <p>I try to write a pytest for my pymodbus RTU server where I want to write a 32bit float encoded value to the server and compare it with the servers own register read method.  The server looks like this:</p>
  <pre class="lang-py prettyprint-override"><code>class ModbusRTUServer:
      P_target_address = 0x33
      def __init__(self, port, timeout, baudrate):
          self.thread = None
          self.port = port
          self.timeout = timeout
          self.baudrate = baudrate
          self.block = ModbusSequentialDataBlock.create()
          self.store = ModbusSlaveContext(hr=self.block, ir=self.block)
          self.context = ModbusServerContext(slaves=self.store)
          self.P_target = 0
  
      def _run_server_threaded(self):
          StartSerialServer(
              self.context,
              framer=ModbusRtuFramer,
              port=self.port,
              timeout=self.timeout,
              baudrate=self.baudrate,
          )
          l.debug(&quot;StartSerialServer() ended.&quot;)
  
      def run_server(self):
          self.thread = Thread(target = self._run_server_threaded)
          self.thread.start()
  
      def stop_server(self):
          StopServer()
  
      def get_P_target_float32(self):
          return BinaryPayloadDecoder.fromRegisters(
              self.block.getValues(ModbusRTUServer.P_target_address, 2), 
              byteorder=Endian.Big, wordorder=Endian.Big
          ).decode_32bit_float()
  </code></pre>
  <p>And here is the test, that does not work:</p>
  <pre class="lang-py prettyprint-override"><code>@patch(&quot;twisted.internet.serialport.SerialPort&quot;)
  def test_modbus_rtu_server_get_P_target_float32_should_be_big_endian_encoded(mock_sp) -&gt; None:
      with patch('twisted.internet.reactor') as mock_reactor:
          m, s = os.openpty()
  
          server = ModbusRTUServer(os.ttyname(s), test_server_timeout, test_server_baudrate)
          server.run_server()
          assert mock_reactor.run.call_count == 1
  
          val_f = -3.33
          builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big)
          builder.add_32bit_float(val_f)
          print(builder.to_registers()) # [49237, 7864]
  
          client = ModbusSerialClient(method='rtu', baudrate=test_server_baudrate, timeout = test_server_timeout, port=os.ttyname(m))
          client.connect()
          assert client.is_socket_open() == True
  
          client.write_registers(ModbusRTUServer.P_target_address, builder.to_registers())
          assert server.get_P_target_float32() &gt;= val_f - 0.01
          assert server.get_P_target_float32() &lt;= val_f + 0.01
  </code></pre>
  <p>These are the log messages I end up with:</p>
  <pre><code>&gt;           assert server.get_P_target_float32() &lt;= val_f + 0.01
  E           assert 4.775518667735688e-39 &lt;= (-3.33 + 0.01)
  E            +  where 4.775518667735688e-39 = &lt;bound method ModbusRTUServer.get_P_target_float32 of &lt;smc.ModbusRTUServer object at 0x7f2353f78d60&gt;&gt;()
  E            +    where &lt;bound method ModbusRTUServer.get_P_target_float32 of &lt;smc.ModbusRTUServer object at 0x7f2353f78d60&gt;&gt; = &lt;smc.ModbusRTUServer object at 0x7f2353f78d60&gt;.get_P_target_float32
  
  tests/test_modbus.py:47: AssertionError
  -------------------------------------------------------------------------------------------------------- Captured log call --------------------------------------------------------------------------------------------------------
  INFO     pymodbus.server.asynchronous:asynchronous.py:327 Starting Modbus Serial Server on /dev/pts/12
  DEBUG    pymodbus.server.asynchronous:asynchronous.py:223 Running in spawned thread
  DEBUG    pymodbus.payload:payload.py:125 [49237, 7864]
  DEBUG    pymodbus.payload:payload.py:125 [49237, 7864]
  DEBUG    pymodbus.transaction:transaction.py:139 Current transaction state - IDLE
  DEBUG    pymodbus.transaction:transaction.py:144 Running transaction 1
  DEBUG    pymodbus.transaction:transaction.py:273 SEND: 0x0 0x10 0x0 0x33 0x0 0x2 0x4 0xc0 0x55 0x1e 0xb8 0x91 0x90
  DEBUG    pymodbus.client.sync:sync.py:76 New Transaction state 'SENDING'
  DEBUG    pymodbus.transaction:transaction.py:287 Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
  DEBUG    pymodbus.transaction:transaction.py:303 Transaction failed. (Modbus Error: [Invalid Message] No response received, expected at least 2 bytes (0 received)) 
  DEBUG    pymodbus.framer.rtu_framer:rtu_framer.py:240 Frame - [b''] not ready
  DEBUG    pymodbus.transaction:transaction.py:465 Getting transaction 0
  DEBUG    pymodbus.transaction:transaction.py:224 Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
  DEBUG    pymodbus.payload:payload.py:312 [52, 52]
  DEBUG    pymodbus.payload:payload.py:368 [b'\x004', b'\x004']
  DEBUG    pymodbus.payload:payload.py:312 [52, 52]
  DEBUG    pymodbus.payload:payload.py:368 [b'\x004', b'\x004']
  
  </code></pre>
  <p>When I run this server on a real serial port connected to another raspi and start the very same client example there, everything works fine.</p>
  <p>I searched in all examples and tests but found no solution for this problem or an example how to make such a test over a real serial port. Any help is very appreciated!</p>