serial-portmodbusmodbus-tcppymodbuspymodbustcp

How to shape a CALL in PYMODBUS (Modicon?)


i am in a serius battle with a solar inverter right know (INGETEAM 3play) i am connected by TCP / IP.

I need to understand how to shape my call becouse i am not having the answer i want, and also i dont' know how many bits i am waiting for an answer. Here is the call i need to do:

Call and answer

I am sure that 01 is the ID 03 means Holding Register, so how do i shape the rest (00 00 00 06)?? This is the code:

FORMAT = ('%(asctime)-15s %(threadName)-15s '
          '%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger('pymodbus.protocol')
log.setLevel(logging.DEBUG)

variables = [0,6,12,18,24,30,36,70,72,74,76,78,342,344]

data = client.read_holding_registers(0, 2, unit=1)
decoder = BinaryPayloadDecoder.fromRegisters(data.registers, Endian.Big)
eastron = round(decoder.decode_32bit_float(), 3)
print (eastron) 

I know i have to play with the client.read_holding_registers, but how? The documentation goes like this: enter image description here

Maybe the fact that is called Modicon is what i am missing?

To sum up the questions:

  1. How to shape my call so it matchs the call 01 03 00 00 00 06?
  2. Why when i do the call 01 03 00 00 00 06 i get all the answers (year to seconds) shouldn't i just get seconds? (thinking that the 30006 in the pdf stands for the call itself 03 00 00 00 06)
  3. How can i log the DEBUG that i get when doing the call? i am doing this in a raspberry and i am not sure that i would be able to see the call like i do on jupyter

example

DEBUG:pymodbus.transaction:Current transaction state - TRANSACTION_COMPLETE
DEBUG:pymodbus.transaction:Running transaction 6
DEBUG:pymodbus.transaction:SEND: 0x1 0x3 0x0 0x0 0x0 0x2 0xc4 0xb
DEBUG:pymodbus.framer.rtu_framer:Changing state to IDLE - Last Frame End - 1580425865.276049, Current Time stamp - 1580425955.463177
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: 0x1 0x3 0x4 0x41 0x60 0x0 0x0 0xee 0x11
DEBUG:pymodbus.framer.rtu_framer:Getting Frame - 0x3 0x4 0x41 0x60 0x0 0x0
DEBUG:pymodbus.factory:Factory Response[ReadHoldingRegistersResponse: 3]
DEBUG:pymodbus.framer.rtu_framer:Frame advanced, resetting header!!
DEBUG:pymodbus.transaction:Adding transaction 1
DEBUG:pymodbus.transaction:Getting transaction 1
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
DEBUG:pymodbus.payload:[16736, 0]
DEBUG:pymodbus.payload:[b'A`', b'\x00\x00']

Thanks in advance!


Solution

    1. How to shape my call so it matchs the call 01 03 00 00 00 06?

    Decoding this we get:

    01 - Unit ID; 1 Byte; 01
    03 - Function code; 1 Byte; 0x03 = Read Holding Registers
    00 00 - Starting Address; 2 Bytes (big-Endian); Address 0
    00 06 - Quantity of Registers; 2 Bytes (big-Endian); Length of 6

    This means the above is a request to Unit ID 1 to 'Read Holding Registers' (3) starting at register 0 returning six registers.

    To duplicate this using pymodbus you would use client.read_holding_registers(0, 6, unit=1).

    1. Why when i do the call 01 03 00 00 00 06 i get all the answers (year to seconds) shouldn't i just get seconds? (thinking that the 30006 in the pdf stands for the call itself 03 00 00 00 06)

    As noted above the request is for six registers (so this includes the full time).

    1. How can i log the DEBUG that i get when doing the call? i am doing this in a raspberry and i am not sure that i would be able to see the call like i do on jupyter

    From your example it looks like you are already generating debug information. As modbus is a standard you should not usually need to look at the bytes being sent/received when using a decent library to handle this for you.