gavinying / modpoll

A New Command-line Tool for Modbus and MQTT
https://gavinying.github.io/modpoll
MIT License
84 stars 17 forks source link

Move to RS485 breaks implementation #35

Closed ennui2342 closed 5 months ago

ennui2342 commented 7 months ago

A while back I added a config for the foxess inverter based on connecting to its ethernet port. In recent updates they've disabled the ethernet port on the inverter, so I have wired into the RS485 serial connection with an Elfin EW11 RS485 Modbus to WiFi.

The recommended test for the other modpoll works as follows:

./modpoll -m tcp -p 502 -a 247 -t 3 -0 -1 -c 16 -r 11000 192.168.0.188
modpoll 3.11 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2024 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.

Protocol configuration: MODBUS/TCP, FC4
Slave configuration...: address = 247, start reference = 11000 (PDU), count = 16
Communication.........: 192.168.0.188, port 502, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, input register table

-- Polling slave...
\[11000]: 1963
[11001]: 0
[11002]: 4
[11003]: 201
[11004]: 0
[11005]: 0
[11006]: 1561
[11007]: 0
[11008]: 0
[11009]: 2415
[11010]: 7
[11011]: -53
[11012]: -21
[11013]: 175
[11014]: 5002
[11015]: 0

But for the life of me I cannot get the python version working. Trying with a simple configuration file of:

device,foxess,1,,
poll,holding_register,11000,1,BE_BE
ref,pv1-voltage,11000,int16,rw,

I get:

python3 -m modpoll --tcp 192.168.0.188 --config a

modpoll - A New Command Line Tool for Modbus

2024-03-10 18:03:23,204 | I | modpoll.main | No MQTT host specified, skip MQTT setup.
2024-03-10 18:03:23,204 | I | modpoll.modbus_task | Loading config from: a
2024-03-10 18:03:23,206 | I | modpoll.modbus_task | Adding new device foxess
2024-03-10 18:03:23,207 | I | modpoll.modbus_task | Add poller (start_address=11000, size=1) to device foxess
2024-03-10 18:03:23,207 | I | modpoll.modbus_task | Polling 1 device(s)...
2024-03-10 18:03:23,208 | I | modpoll.main |  ====== modpoll polling at rate:10.0s, actual:10.0s ======
2024-03-10 18:03:26,263 | E | modpoll.modbus_task | Reading device:foxess, FuncCode:3, Start_address:11000, Size:1... ERROR

I've tried a lot of variations but can't get past this. Do you have any ideas for what's happening here? I'd love to contribute an updated config.

-Mark

gavinying commented 7 months ago

Hi Mark, the slave ID (or Modbus Address) shall be 247 after comparing the configs, could you try with below config,

device,foxess,247,,
poll,holding_register,11000,1,BE_BE
ref,pv1-voltage,11000,int16,rw

If the issue is not solved, please update modpoll to the latest version (0.7.x) and share your logs in debug mode,

python3 -m modpoll --tcp 192.168.0.188 --config a -1 --loglevel DEBUG

Thanks.

ennui2342 commented 7 months ago

Thanks for the quick reply Gavin. I did actually try the 247 - wasn't sure whether that was just an ID or acted as the slave ID so I gave it a try, but no luck. Here's the debug log:

2024-03-11 10:05:23,270 | I | modpoll.main | No MQTT host specified, skip MQTT setup.
2024-03-11 10:05:23,270 | I | modpoll.modbus_task | Loading config from: a
2024-03-11 10:05:23,272 | I | modpoll.modbus_task | Adding new device foxess
2024-03-11 10:05:23,272 | I | modpoll.modbus_task | Add poller (start_address=11000, size=1) to device foxess
2024-03-11 10:05:23,272 | D | modpoll.modbus_task | Add reference pv1-voltage to device foxess
2024-03-11 10:05:23,272 | I | modpoll.modbus_task | Polling 1 device(s)...
2024-03-11 10:05:23,273 | I | modpoll.main |  ====== modpoll polling at rate:10.0s, actual:10.0s ======
2024-03-11 10:05:24,281 | D | pymodbus.logging | Connection to Modbus server established. Socket ('192.168.0.193', 54671)
2024-03-11 10:05:24,282 | D | modpoll.modbus_task | Master connected. Delay of 0 seconds.
2024-03-11 10:05:24,282 | D | modpoll.modbus_task | Polling device foxess ...
2024-03-11 10:05:24,282 | D | pymodbus.logging | Current transaction state - IDLE
2024-03-11 10:05:24,282 | D | pymodbus.logging | Running transaction 1
2024-03-11 10:05:24,282 | D | pymodbus.logging | SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0xf7 0x3 0x2a 0xf8 0x0 0x1
2024-03-11 10:05:24,282 | D | pymodbus.logging | New Transaction state "SENDING"
2024-03-11 10:05:24,283 | D | pymodbus.logging | Changing transaction state from "SENDING" to "WAITING FOR REPLY"
2024-03-11 10:05:25,710 | D | pymodbus.logging | Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
2024-03-11 10:05:25,711 | D | pymodbus.logging | RECV: 0x0 0x1 0x0 0x0 0x0 0x3 0xf7 0x83 0x2
2024-03-11 10:05:25,711 | D | pymodbus.logging | Processing: 0x0 0x1 0x0 0x0 0x0 0x3 0xf7 0x83 0x2
2024-03-11 10:05:25,711 | D | pymodbus.logging | Factory Response[131]
2024-03-11 10:05:25,711 | D | pymodbus.logging | Adding transaction 1
2024-03-11 10:05:25,711 | D | pymodbus.logging | Getting transaction 1
2024-03-11 10:05:25,711 | D | pymodbus.logging | Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
2024-03-11 10:05:25,712 | E | modpoll.modbus_task | Reading device:foxess, FuncCode:3, Start_address:11000, Size:1... ERROR
2024-03-11 10:05:25,712 | D | modpoll.modbus_task | Exception Response(131, 3, IllegalAddress)
gavinying commented 7 months ago

Thanks for your sharing, from the log, it tells us

  1. The device correctly responsed to the request (instead of timeout), meaning modbus communication is good;
  2. The error message is IllegalAddress, which means our requested address 11000 might be wrong;

Due to the changes (disable ethernet port) you mentioned above, there might be register address change as well. In many cases, device vendor will map the internal values to RTU and TCP ports in different address spaces. If you have updated manual, please double check the register address accordingly.

FYI, I did some search on google, someone mentioned a different addresses, e.g. 31000 under LAN https://github.com/StealthChesnut/HA-FoxESS-Modbus/wiki/Data-Register-Reference---H1-AC1

Hope it helps. Gavin

ennui2342 commented 7 months ago

Thanks Gavin - not what I expected! I've moved from the LAN interface to a direct RS485 interface being bridged by the Elfin device to wifi. I expected this would mean I would need to switch from the 30000 range of addresses to the 10000 range. I didn't question this because the modpoll.exe query I shared in my post did work against the 10000 addresses so I assumed that was right, and my old configuration file against the 30000 range wasn't working.

The thing that had changed was the need for the right ID. So the old config file when changed to 247 retries the right data. So at it's now working! However I am still very confused by the fact that modpoll.exe finds the data in the 10000 range and the python implementation gets it from the 30000 range. It shouldn't matter the client I use! I'm not sure what the two clients are doing differently.

It is now working though, so thank you very much for your help. The 247 was the key with the LAN address space even though I'm no longer using the LAN! Cheers.

-Mark

gavinying commented 7 months ago

Hi Mark, good to hear that it is now working!

Now let me try to clear your confusion, the reason we have two sets of address spaces is because the device vendor implements both Modbus-RTU and Modbus-TCP protocols in the corresponding address spaces, both spaces are mapped to the same actual data.

So, theoritically, we can use either address space to retrieve the same data, but notice we need to use different data framer to parse received data. See this issue https://github.com/gavinying/modpoll/issues/30 for details.

Luckily, specifying data framer has been supported in the latest version of modpoll v0.7.0+, you can try the following two commands, both shall work if my guess is right,

Use TCP framer

Run command modpoll --tcp 192.168.0.188 --config a with

device,foxess,247,,
poll,holding_register,31000,1,BE_BE
ref,pv1-voltage,31000,int16,rw

Use RTU framer

Run command modpoll --tcp 192.168.0.188 --framer rtu --config b with

device,foxess,247,,
poll,holding_register,11000,1,BE_BE
ref,pv1-voltage,11000,int16,rw
ennui2342 commented 7 months ago

Thanks for the great explanation - I had spotted that issue and that you'd added the framer arg when I was trying to debug it and tried the rtu framer as I thought that might be the difference (seems I was almost there!). However, when I've added this argument I got no response from the Elfin EW11.

Digging a bit further, on the EW11 web config I've changed the serial protocol setting from 'modbus' to 'frame' (defaults of: frame length 16, frame time 100ms, tag off). This does then talk to modpoll when using --framer rtu, but still only on the 31000 addresses! Strange.

gavinying commented 5 months ago

Close due to inactivity.