1

I want to comunicate a PC with a smart meter which allows Modbus TCP communication, the PC will be the master and I just need read holding registers and show them in float format. I'm using python with pymodbus 2.2.0 My code is:

from pymodbus.client.sync import ModbusTcpClient

client = ModbusTcpClient('169.254.00.10')

result = client.read_holding_registers(1845,1,unit=0x01)
print('**************************************************************')
print(result)
client.close()

what I get is:

DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x1 0x3 0x7 0x35 0x0 0x1
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x0 0x1 0x0 0x0 0x0 0x5 0x1 0x3 0x2 0x6 0xc
DEBUG:pymodbus.framer.socket_framer:Processing: 0x0 0x1 0x0 0x0 0x0 0x5 0x1 0x3 0x2 0x6 0xc
DEBUG:pymodbus.factory:Factory Response[ReadHoldingRegistersResponse: 3]
DEBUG:pymodbus.transaction:Adding transaction 1
DEBUG:pymodbus.transaction:Getting transaction 1
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
**************************************************************
ReadRegisterResponse (1)

Do you know how to resolve it using pymodbus 2.2.0?

Andres AC
  • 13
  • 4

1 Answers1

1

You have to extract the registers from your response, try this:

print(result.registers)

Or, if you want them one by one:

for reg in result:
    print(reg)

If you're not sure if your server is running, its IP or port it's a good idea to use a standalone tool to test, if you are on Windows you can use QModMaster to make sure your setting and mapping.

And note that with just one Modbus register you cannot get a float because Modbus register are 16 bits integers. If you want to get a float you need to read two registers.

If, on the other hand, you only want to verify your client-side code you can run this example on your computer simultaneously with your client code. Of course, you have to change the IP address on your script to localhost, the port to 5020 and the register number you're reading to a lower number (or increase the size of the server datastore). If you're on Windows you might need to disable or create a rule on your firewall.

Marcos G.
  • 3,371
  • 2
  • 8
  • 16
  • I tried print(result.registers) but I get this error: AttributeError: 'ExceptionResponse' object has no attribute 'registers'. Only I need to convert result wich is only one register to float and show it. – Andres AC Jun 13 '19 at 17:33
  • Are you sure your server is up and running? The error you got means you did not get any data back. What exactly is your server? Your instantiation does not state a port number, is it running on port 502? – Marcos G. Jun 13 '19 at 17:35
  • I just noticed that the log you posted on your question shows that you're actually getting the register, so `print(result.registers)` should be working. Have you got the same log together with the error?. According to the manual on your link port should be the default 502, so you should be fine on that side... – Marcos G. Jun 13 '19 at 18:16
  • Thanks for your help, it was just a error with the register number, print(result.registers) works with my code. – Andres AC Jun 14 '19 at 03:58
  • Great, enjoy interacting with your device, you have a lot of registers in there to play with – Marcos G. Jun 14 '19 at 04:18