1
votes

I am trying with the interactive version of pymodbus (pip install pymodbus[repl]) to access a modbus device (UPS). I had accessed it by using mbpoll tool, so the communication and device are both working. I guess I am having problems to figure out what are the "right" parameters that match the equivalent mbpoll.

From documentation, I am trying to access the values starting at 30405 (page 864 liebert-intellislot-modbus-rtu-reference-guide-SL-28170_0.pdf) what I understand as holding registers as the function is 30xxx:

pg 864 - Vertiv™ | Liebert® IntelliSlot Modbus/BACnet Reference Guide

Table 3.118 Liebert® GXT5—Input and Holding (continued)
           
          Data Label                             Input      Holding   # of Reg   Scale    Notes/Units
          System Input Frequency                  30405           —       1        10     Uint16
          System Input Power Factor L1            30406           —       1       100     Uint16
          System Input Power Factor L2            30407           —       1       100     Uint16
          System Input Power Factor L3            30408           —       1       100     Uint16
          System Input Max Voltage L1-N           30409           —       1        10     Uint16
          System Input Min Voltage L1-N           30410           —       1        10     Uint16
          System Input Max Voltage L2-N           30411           —       1        10     Uint16
          System Input Min Voltage L2-N           30412           —       1        10     Uint16
          System Input Max Voltage L3-N           30413           —       1        10     Uint16

Using the mbpool it returns values as expected:

    mbpoll  -r 396 -t 3 -c 125 -1 -q 192.168.160.1  | \grep -v "65535 (-1)"
    -- Polling slave 1...
    [396]:  2162
    [402]:  7
    [405]:  599
    [406]:  53
    [409]:  2279
    [410]:  2048
    [415]:  230
    [416]:  27
    [417]:  60
    [418]:  1
    [419]:  0
    [420]:  190
    [431]:  2163
    [434]:  599
    [435]:  230
    [446]:  2
    [447]:  0
    [448]:  1
    [449]:  0
    [450]:  1
    [451]:  0
    [452]:  14446
    ...

Then I fired /usr/local/bin/pymodbus.console tcp --host 192.168.160.1 --port 502 and at prompt I've tried several combinations of client.read_holding_registers only to get the "message": "IllegalAddress" for all trials below (and others, varying count, unit, addresses, etc):

    client.read_holding_registers address=30396 count=10 unit=1
    client.read_holding_registers address=396 count=10 unit=1
    client.read_holding_registers address=30396 count=10 unit=0
    client.read_holding_registers address=396 count=10 unit=0

The complete return of one of theses client.read is:

    > client.read_holding_registers address=396 count=10 unit=0
    {
        "original_function_code": "3 (0x3)",
        "error_function_code": "131 (0x83)",
        "exception code": 2,
        "message": "IllegalAddress"
    }

Since it is returning valid values from mbpoll, I suspect I am doing something wrong with the parameters of client.read_holding_registers, but I can't figure out where is the problem.

Both access are from the same machine, at the same time, running opensuse tumbleweed. Accessing as root or normal user does not make any difference.

I appreciate any hints to deal with the register address with pymodbus module.


1
I think the mbpoll command line options may be causing the confusion here -t 3 16-bit input register data type (see this issue). This matches the manual; you want input, not holding registers, so try client.read_input_registers address=30396 count=10,Brits
Yes ! "client.read_input_registers address=396 count=100" worked ! Thanks for the link, so mbpoll is confused by design (LOL) ! PS: Note the address is only the "xxx" part of 30xxx address, so it is similar to mbpoll addresss schema.Miguel Rozsas
Errata: In fact mbpoll address starts at 1 (which match device documentation addresses) and pymodbus starts at 0, so the equivalent mbpoll -r 385 should be in pymodbus address=384, both limited to count 125 max.Miguel Rozsas
Sorry, was going to mention that (I use other libraries and could not see whether pymodbus used registers or addresses from a quick look - it gets confusing). Also only just noticed that I put 30396 rather than 396 (which should have been 395).Brits

1 Answers

1
votes

As per the comments the mbpoll command line options can cause some confusion:

-t 3:int16 16-bit input register data type with signed int display
-t 4 16-bit output (holding) register data type (default)

This is confusing because the modbus command to read an input register is 4 and for holding registers its 3 (so the reverse of the mbpoll arguments). This is mentioned in an issue.

So the command you need will be client.read_input_registers address=395 count=10 (as per the comments there is also an issue with register numbering - the "Modbus: When 40001 Really Means 1, or 0 Really Means 1 " section in this article explains this well).