Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request, read all modbus meters and also log voltage, cos phi etc #132

Open
fluppie opened this issue Apr 30, 2023 · 84 comments
Open

Comments

@fluppie
Copy link

fluppie commented Apr 30, 2023

Currently I have a ESP32 with modbus shield from enri.nl to read all parameters / all modbusmeters. This gives 2 modbus masters which is far from ideal. I don't know if it's a lot of work to read out more registers than current and power as well as kWh import / export.

Screenshot of the ESP32 with ESPEasy software:
afbeelding

The Nan values are because of modbus collisions. I think the SmartEVSE is requesting every 2 seconds data on the modbus. My mainsmeter is at 15s intervals and the PV and EV meter are at 60s intervals. To limit the number of collisions.

List with all available registers:
https://github.com/reaper7/SDM_Energy_Meter/blob/master/SDM.h

afbeelding

Just a question, if not I keep using it like this. On the other hand I can save a ESP32, a 5V power supply and modbus collisions :).

@Ferforfaen
Copy link

I would love that!

I have tried to do readouts with two masters, but failed.

@dingo35
Copy link

dingo35 commented Apr 30, 2023

I am thinking about a sort of configurable gateway from modbus to REST API....

@fluppie
Copy link
Author

fluppie commented Apr 30, 2023

Or an implementation of Modbus TCP, so all Modbus RTU devices can also be read/controlled over Modbus TCP. But I think it would be enough to go full read-out with SmartEVSE v3 and then using the REST API to send Modbus meter data to Home Assistant or other HA systems.
I do like the fact that inter SmartEVSE communication is RTU RS485, so Sensorbox can be far away of the SmartEVSE or for example one electrical cabinet with 4 SmartEVSE's talking to another board with 4 EVSE's 20-30m away. Same story for the sensorbox. In large industrial sites the main board where power from the netdistributor or own local transformator can be quite far away from the electrical cabinets with SmartEVSE's.

@dingo35
Copy link

dingo35 commented May 1, 2023

modbus-tcp-bridge.zip

In this version your MainsMeter, EVMeter and PVMeter present themselves at port 502 of your SmartEVSE, with the modbus-tcp protocol; so this makes it possible for you to use whatever modbus function you want on whatever modbus register you want.
E.g. my MainsMeter is at slave address 0x0a, so this command reads register 70decimal and following:
mbpoll -a10 -t 3:hex -r 70 -c 10 10.0.0.76

Please test, have fun!

@fluppie
Copy link
Author

fluppie commented May 1, 2023

Looks like it's working can it interfere with the SmartEVSE RTU modbus polling? I mean can the TCP requests from HA happen on the same time as the SmartEVSE is polling this data from the RTU modbus?
afbeelding

Because sometimes I see this:
afbeelding

Home Assistant yaml config

modbus: 
  - type: tcp
    host: 192.168.1.119 # ip van smartevse v3
    port: 502
    name: "smartevsev3modbustcp"
    close_comm_on_error: true
    delay: 3
    timeout: 5
    sensors:
      - name: sdm230_phase_1_line_to_neutral_volts
        slave: 101
        address: 0
        input_type: input
        count: 2
        precision: 2
        data_type: float32
        unit_of_measurement: V
        device_class: voltage
        scan_interval: 10
      - name: sdm230_phase_1_current
        slave: 101
        address: 6
        input_type: input
        count: 2
        precision: 2
        data_type: float32
        unit_of_measurement: A
        device_class: current
        scan_interval: 10
      - name: sdm230_phase_1_power
        slave: 101
        address: 12
        input_type: input
        count: 2
        precision: 3
        data_type: float32
        unit_of_measurement: W
        device_class: power
      - name: sdm230_phase_1_va
        slave: 101
        address: 18
        input_type: input
        count: 2
        precision: 2
        data_type: float32
        unit_of_measurement: VA
        device_class: power

@dingo35
Copy link

dingo35 commented May 1, 2023

Thats why I ask you to test it thoroughly: it uses the same client (=modbus server) as the rest of the firmware, so I would expect no collisions. But I enabled modbus lowlevel error routine, so if you have telnet log running you should see no timeout or other modbus errors...

@fluppie
Copy link
Author

fluppie commented May 1, 2023

Without disconnecting the second ESP32 module with ESPEasy firmware, CRC errors 99% sure coming from the second modbusmaster trying to fetch data:

(MBhandleError)(C0) Error response: E2 - CRC check error
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 0.0 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: -9.6 A L2: 0.0 A L3: 0.0 A Isum: -9.6 A
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E2 - CRC check error
(MBhandleError)(C0) Error response: E2 - CRC check error
(MBhandleError)(C0) Error response: E2 - CRC check error
(MBhandleError)(C0) Error response: E2 - CRC check error
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E2 - CRC check error
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(MBhandleError)(C0) Error response: E0 - Timeout
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 0.0 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: -9.6 A L2: 0.0 A L3: 0.0 A Isum: -9.6 A
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E2 - CRC check error
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(MBhandleError)(C0) Error response: E2 - CRC check error
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(MBhandleError)(C0) Error response: E0 - Timeout
(loop)(C1) 1 clients running.
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 0.0 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: -9.6 A L2: 0.0 A L3: 0.0 A Isum: -9.6 A
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E2 - CRC check error
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(MBhandleError)(C0) Error response: E2 - CRC check error
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E4 - Server ID mismatch
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 0.0 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: -9.6 A L2: 0.0 A L3: 0.0 A Isum: -9.6 A
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout

After disconnecting the second ESP32 modbus device:

(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 0.0 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: -6.5 A L2: 0.0 A L3: 0.0 A Isum: -6.5 A
(MBhandleError)(C0) Error response: E0 - Timeout
(loop)(C1) 0 clients running.
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 0.0 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: -6.5 A L2: 0.0 A L3: 0.0 A Isum: -6.5 A
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 0.0 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: -6.4 A L2: 0.0 A L3: 0.0 A Isum: -6.4 A
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 0.0 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: -6.5 A L2: 0.0 A L3: 0.0 A Isum: -6.5 A
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 0.0 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: -6.6 A L2: 0.0 A L3: 0.0 A Isum: -6.6 A
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(MBhandleError)(C0) Error response: E0 - Timeout
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 0.0 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: -6.5 A L2: 0.0 A L3: 0.0 A Isum: -6.5 A
(MBhandleError)(C0) Error response: E0 - Timeout

afbeelding

@dingo35
Copy link

dingo35 commented May 1, 2023

Ok going to try second setup... stay tuned!

@dingo35
Copy link

dingo35 commented May 1, 2023

modbus-tcp-bridge2.zip
This any better?

@fluppie
Copy link
Author

fluppie commented May 1, 2023

No, E0 Time out remains.
I also have the impression I see more "niet beschikbaar" when monitoring the sensors. What parameter(s) did you change?
afbeelding

@dingo35
Copy link

dingo35 commented May 1, 2023

I did add another, separate client for the TCP bridge.

Now are you polling the extra registers you requested or are you also polling the registers that are already available through the REST API? Because that would definitely mess up traffic on the bus....

@dingo35
Copy link

dingo35 commented May 2, 2023

When I try to copy your setup, I get this error in HomeAssistant:
WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.sdm230_phase_1_va (<class 'homeassistant.components.modbus.sensor.ModbusRegisterSensor'>) is using native unit of measurement 'VA' which is not a valid unit for the device class ('power') it is using; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+modbus%22

And also, every 30 seconds I get this:
May 2 07:28:24 backupserver hass[30207]: 2023-05-02 07:28:24.716 ERROR (SyncWorker_3) [homeassistant.components.modbus.modbus] Pymodbus: smartevsev3modbustcp: Exception Response(132, 4, None)

When I comment out the device_class: power of this sensor, both messages are gone. I still get an occasional timeout in telnet but not as many as you do .... would this change anything in your setup?

EDIT: Testing with the FIRST firmware file modbus-tcp-bridge.zip since this makes more sense.

@dingo35
Copy link

dingo35 commented May 2, 2023

I cannot get the timeouts reproduced in my setup; I get an occasional timeout, but this is not often enough to do some decent testing.

I can see the following test scenarios:

  1. I can compile a 1.6.1 version (without the modbus TCP bridge) that has the Modbus error messages enabled (for some reason they were disabled until now), to make sure you didn't have timeout messages all the time (without the bridge component)
  2. You can add some statements to your configuration.yaml to see if this has any influence:
  • type: tcp
    host: 10.0.0.76 # ip van smartevse v3
    port: 502
    name: "smartevsev3modbustcp"
    close_comm_on_error: true
    delay: 3
    timeout: 5
    #close_comm_on_error: false
    #retry_on_empty: true
    #retries: 10
    #delay: 10
    #message_wait_milliseconds: 1000
    #timeout: 10

This represents your setup, if you use the commented parameters this might improve the behaviour of HomeAssistant.

Let me know which way you want to go....

@dingo35
Copy link

dingo35 commented May 2, 2023

For test scenario 1 you can use
https://github.com/serkri/SmartEVSE-3/releases/tag/v1.6.2

since it has no modbus TCP bridge, but it does have the extended log messages for modbus errors.

@fluppie
Copy link
Author

fluppie commented May 2, 2023

OK great, will look into this. Possible that the current 1.6.2 release has Telnet disabled?

@dingo35
Copy link

dingo35 commented May 3, 2023

You've got to rename firmware.debug.bin to firmware.bin

@deekoowee
Copy link

This is interesting.
Modbus TCP could be also a solution to my #121

Could it be possible to have modbus TCP addressing for the meters ?

I have tested the Elfin EW11 devices to convert modbus RTU to modbus TCP.
EW11 is modbus bridge and can serve the data to several TCP ports.

@dingo35
Copy link

dingo35 commented May 4, 2023

It would not solve the problem that your MainsMeter is fixed as slave at address 1, and SmartEVSE is fixed as master at address 1.

@fluppie
Copy link
Author

fluppie commented May 4, 2023

Finally had some time to flash the debug version (from the now pulled 1.6.2) , stupid me, not checking the whole folder contents...

(D) (CalcBalancedCurrent)(C0) Balance: EVSE0:A(0.0A),EVSE1:A(0.0A),EVSE2:A(0.0A),EVSE3:A(0.0A),EVSE4:A(0.0A),EVSE5:A(0.0A),EVSE6:A(0.0A),EVSE7:A(0.0A),
(D) (ModbusWriteMultipleRequest)(C0) Sent packet(ModbusWriteMultipleRequest)(C0) address: 09, function: 0x10, reg: 0020, count: 8, values: 0000 0000 0000 0000 0000 0000 0000 0000 019c 0021 0000 0021 0000 0000 014a 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 .
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 3.3 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: 3.3 A L2: 0.0 A L3: 0.0 A Isum: 3.3 A
(MBhandleError)(C0) Error response: E0 - Timeout
(D) (Timer100ms)(C0) ModbusRequest 3: Request MainsMeter Measurement
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 65, function: 04, reg: 0006, data: 000c.
(D) (ModbusDecode)(C0) Received packet(ModbusDecode)(C0)  (27 bytes) 65 04 18 40 56 e6 f5 00 00 00 00 00 00 00 00 44 17 a1 9f 00 00 00 00 00 00 00 00
(V) (ModbusDecode)(C0)  valid Modbus packet: Address 65 Function 04
(V) (ModbusDecode)(C0)  Register 0006(ModbusDecode)(C0)  Response
(D) (Timer100ms)(C0) ModbusRequest 5: Request Energy Node 0
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 66, function: 04, reg: 0048, data: 0002.
(D) (ModbusDecode)(C0) Received packet(ModbusDecode)(C0)  (7 bytes) 66 04 04 45 98 0d 3f
(V) (ModbusDecode)(C0)  valid Modbus packet: Address 66 Function 04
(V) (ModbusDecode)(C0)  Register 0048(ModbusDecode)(C0)  Response
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 66, function: 04, reg: 000c, data: 0002.
(D) (ModbusDecode)(C0) Received packet(ModbusDecode)(C0)  (7 bytes) 66 04 04 00 00 00 00
(V) (ModbusDecode)(C0)  valid Modbus packet: Address 66 Function 04
(V) (ModbusDecode)(C0)  Register 000c(ModbusDecode)(C0)  Response
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 02, function: 04, reg: 0000, data: 0008.
(MBhandleError)(C0) Error response: E0 - Timeout
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 03, function: 04, reg: 0000, data: 0008.
(MBhandleError)(C0) Error response: E0 - Timeout
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 04, function: 04, reg: 0000, data: 0008.
(MBhandleError)(C0) Error response: E0 - Timeout
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 05, function: 04, reg: 0000, data: 0008.
(MBhandleError)(C0) Error response: E0 - Timeout
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 06, function: 04, reg: 0000, data: 0008.
(MBhandleError)(C0) Error response: E0 - Timeout
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 07, function: 04, reg: 0000, data: 0008.
(MBhandleError)(C0) Error response: E0 - Timeout
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 08, function: 04, reg: 0000, data: 0008.
(MBhandleError)(C0) Error response: E0 - Timeout
(D) (Timer100ms)(C0) ModbusRequest 21: Request EVMeter Current Measurement
(D) (ModbusSend8)(C0) Sent packet(ModbusSend8)(C0) address: 66, function: 04, reg: 0006, data: 000c.
(D) (ModbusDecode)(C0) Received packet(ModbusDecode)(C0)  (27 bytes) 66 04 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
(V) (ModbusDecode)(C0)  valid Modbus packet: Address 66 Function 04
(V) (ModbusDecode)(C0)  Register 0006(ModbusDecode)(C0)  Response
(V) (CalcBalancedCurrent)(C0) Checkpoint 1 Isetbalanced=41.2 A Imeasured=3.3 A MaxCircuit=33 Imeasured_EV=0.0 A, Battery Current = 0.0 A, mode=1.
(V) (CalcBalancedCurrent)(C0) Checkpoint 2 Isetbalanced=41.2 A, Idifference=33.0, mod=0.
(V) (CalcBalancedCurrent)(C0) Checkpoint 4 Isetbalanced=41.2 A.
(V) (CalcBalancedCurrent)(C0) Checkpoint 5 Isetbalanced=41.2 A.
(D) (CalcBalancedCurrent)(C0) Balance: EVSE0:A(0.0A),EVSE1:A(0.0A),EVSE2:A(0.0A),EVSE3:A(0.0A),EVSE4:A(0.0A),EVSE5:A(0.0A),EVSE6:A(0.0A),EVSE7:A(0.0A),
(D) (ModbusWriteMultipleRequest)(C0) Sent packet(ModbusWriteMultipleRequest)(C0) address: 09, function: 0x10, reg: 0020, count: 8, values: 0000 0000 0000 0000 0000 0000 0000 0000 019c 0021 0000 0021 0000 0000 014a 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 .
(I) (printStatus)(C0) STATE: A Error: 0 StartCurrent: -4 ChargeDelay: 0 SolarStopTimer: 0 NoCurrent: 0 Imeasured: 3.3 A IsetBalanced: 41.2 A
(I) (printStatus)(C0) L1: 3.3 A L2: 0.0 A L3: 0.0 A Isum: 3.3 A

Second ESP32 modbus module is disconnected. So don't really get why I get the timeouts. My meters have 101, 102, 103 and 104 as modbus address.

@fluppie
Copy link
Author

fluppie commented May 4, 2023

Got it, it's because Load balancing is set to master and no slaves are connected. In the past we had to this to get the Circuit menu option. In newer releases this is not needed anymore, disabling this fixed the timeouts :).

@dingo35
Copy link

dingo35 commented May 5, 2023

Ok thx for discovering this. So does this also solve your timeout problems for modbus-tcp-bridge.zip?

@fluppie
Copy link
Author

fluppie commented May 5, 2023 via email

@dingo35
Copy link

dingo35 commented May 5, 2023

I have a nice weekend present for you, this version has the problems in 1.6.2 fixed, and also has added detailed logging to the timeout/other modbus error messages; thanks to your trick to put LoadBl = 1 I could test this now!

In normal logging the timeout-messages to the slaves are suppressed, in verbose logging they are still shown... Also a broadcast message that times out will show up if you have loadbalancing enabled without extra EVSE's connected, this one is not suppressed since it is not that annoying...

Let me know what happens if you add more meters!
modbus-tcp-bridge3.zip

@fluppie
Copy link
Author

fluppie commented May 5, 2023

afbeelding
This is fun, so address 101 and 102 are known by the SmartEVSE. Modbus address 103 (solar kWh meter) and 104 (EV2 kWh meter) are not used/known by SmartEVSE. Is it a pure coincidence that these addresses are not read? Or is the SmartEVSE actively blocking all modbus traffic except messages coming from known addresses? Load balancing is disabled.

@dingo35
Copy link

dingo35 commented May 5, 2023

Currently only traffic for the MainsMeter address, the EVmeter address and the PVmeter address is forwarded.

The forwarding has to be configured per address at the RTU modbus, so if you want more addresses to be read a config routine has to be built...

@fluppie
Copy link
Author

fluppie commented May 5, 2023

Yes, would be nice if we could add addresses to the list. I also think PV_Meter / PVmeter is not used anymore. I'm not able to find the menu option for it, I can remember with a v2 or v3 with original firmware this menu item was somewhere. Only MainsM and EVM show up.

@dingo35
Copy link

dingo35 commented May 5, 2023

I think it depends on the setting MainsMeterMeasure...

@fluppie
Copy link
Author

fluppie commented May 5, 2023

Indeed, you can enable it by changing in the menu what the mains meter measures.
afbeelding

Would you need to add menu's like "Extra kWh meter 1" "Extra kWh meter 2" etc? So you can also put more modbus devices in.
I have a second SmartEVSE with also an EV meter for the second (future) EV. How will that work out when they are in master/slave, for now they're not linked/used. Does the master SmartEVSE fetch the modbus data of EV Meter 2 or will the slave do that on his own? Or should I just wire up everything and see what happens :).

@fluppie
Copy link
Author

fluppie commented May 6, 2023

Looks like I can't use the mainsmeter setting with PV :). Purple is sensorbox data to my second SmartEVSE (for now a separate modbus network) and blue the data from the first SmartEVSE with several SDM230's.
afbeelding

Yesterday was with the old working settings, then the data is very similar.

Can I see anywhere what kind of code you added to make the TCP Modbus server?

@dingo35
Copy link

dingo35 commented May 6, 2023

I pushed the code to master, Im thinking of detecting TCP requests that are not yet forwarded and opening a forward for them dynamically; not sure if it can be done simply in the emodbus library...

@fluppie
Copy link
Author

fluppie commented Jun 21, 2023

I think beginning of July I have some more time to test this version. At the moment I run the latest build with the Modem features.

@dingo35
Copy link

dingo35 commented Jun 21, 2023

tcpbridge_with_modem.zip
@fluppie , if it helps you, this is current master (including Arend Jan's modem code) + the patch to test, so you can keep on using the modem stuff during testing....

@hp197
Copy link

hp197 commented Jun 21, 2023

Hi sorry, I haven't got time yet to test it.
That's mainly because I need to rework my data collector to send a http request to open up the bridge.

@arpiecodes
Copy link

arpiecodes commented Jul 6, 2023

I also recently 'migrated' my EV meter to modbus because of the addition of the TCP Modbus bridge (before it was pushing in the relevant EV meter details through MQTT on SmartEVSE from HA, which worked very well). Now I see a lot of bogus values appearing. E.g. big jumps in amperage values for the EV meter, big jumps in 'ChargePower' aka the power in watts being transferred into the EV, while nothing is flowing through.. It seems like some sort of corruption of the values or the checksum not being checked properly. Is this a known issue?

Screenshot 2023-07-06 at 13 02 01

Screenshot 2023-07-06 at 13 02 45

PS: I am using the Sensorbox as well, with my own ESPHome fork running on it. Its hardcoded on slave address 10, EV Meter is on 11. The Sensorbox values are coming in correctly; no weird stuff happening there.

PS2: Apparently only the values that get processed inside of EVSE get scrambled. It seems like the values bridged over by Modbus TCP bridge into HA are actually valid and do not contain the same jumps. Whut?

@dingo35
Copy link

dingo35 commented Jul 6, 2023

Thanks for testing, this is new info since the others in this thread didnt have time to test it.

If I understand correctly :
Your sensorbox on modbus 10 gives good values in SmartEVSE and over the tcp bridge;
Your EVmeter on modbus 11 gives strange values in SmartEVSE but correct values over the tcp bridge.
Correct?

@arpiecodes
Copy link

arpiecodes commented Jul 6, 2023

I must not forget to mention that this is with the Modbus Bridge logic incorporated in the current master branch, not the custom build versions that were shared in this pull request thread.

Your sensorbox on modbus 10 gives good values in SmartEVSE and over the tcp bridge;
Your EVmeter on modbus 11 gives strange values in SmartEVSE but correct values over the tcp bridge.

The Sensorbox is not read out through the modbus bridge (only by SmartEVSE) but directly connected to HA through ESPHome.

Since the whole reason I moved the EV meter from HA to SmartEVSE was the TCP Bridge functionality, being able to still read out all values in HA as well while keeping the EVSE stuff functioning independent from my WiFI/HA etc. So I am actually not sure whether this issue also occurs without using the Modbus bridge functionality.. I may have to do some testing soon to confirm that. I do see some Modbus communication CRC/timeout errors appearing from time to time, in the debug output on telnet. I do not use load balancing btw.

@arpiecodes
Copy link

arpiecodes commented Jul 16, 2023

Small update; somehow it fixed itself; I'm not getting weird values anymore through MQTT.. I'll keep an eye on it and report back if the situation changes again.

@hp197
Copy link

hp197 commented Jul 24, 2023

Holiday season started, so again a bit more time for other projects :)

I tested the code, it works but it is lacking the feature to get the current status.
I have a custom written python application who read the modbus data and put them into mqtt and expose them in prometheus. You’ll have no idea at all if the activation of the bridge is already done and the only solution to this is to spam the url endpoint every x time.

I have 3 concurrent meters and works.

@dingo35
Copy link

dingo35 commented Jul 24, 2023

Ok thx for testing!

@dingo35 dingo35 closed this as completed Jul 24, 2023
@arpiecodes
Copy link

arpiecodes commented Jul 28, 2023

Small update; somehow it fixed itself; I'm not getting weird values anymore through MQTT.. I'll keep an eye on it and report back if the situation changes again.

Sadly it wasn't fixed; my HA installation just wasn't querying the modbus bridge TCP server. After I 'fixed' this and started requesting all SDM630 values again, the same issue came back. It seems to directly garble the information it gets from the SDM630, as if requests for the same register are colliding or something, resulting in weird measurements.

I guess I can try removing the 'double register' reads from HA and see if that fixes the issue (trust the bridge will then forward all incoming data from the SmartEVSE's own requests to HA as well).

@dingo35 dingo35 reopened this Jul 28, 2023
@dingo35
Copy link

dingo35 commented Jul 28, 2023

I would appreciate it if you could test disabling the "double register reads"!

@arpiecodes
Copy link

I would appreciate it if you could test disabling the "double register reads"!

This didn't work sadly. For now I've resorted again to disabling the readings from HA. It's been stable ever since again.

@dingo35
Copy link

dingo35 commented Sep 7, 2023

This is strange, since the HA readings (both MQTT or REST API) dont force any extra readings from the modbus.

It looks like some overload (memory and/or cpu) that is not happening when reading directly through modbus tcp...

@arpiecodes
Copy link

arpiecodes commented Oct 1, 2023

I also noticed quite some errors (timeouts, CRC mismatches) inside of the telnet debug output. It indeed looked to be some kind of overload happening. The errors occurred at both the SDM630 as EV Meter and the Sensorbox v2 as MainsMeter (even though it runs my custom ESPHome FW). I also noticed the Sensorbox being slow and noticing the DSMR component calls were stalling the loop with 0.2s every time it was updating it's values.

Knowing this, I did a couple of things;

  • Put the Modbus requests in SmartEVSE in it's own timer task running every 200ms (instead of co-located with the lock logic in the 100ms timer), which effectively reduces the amount of data requests across the board, hopefully lowering the EVSE load a bit. As far as I could see and after my initial testings, this does not cause any issues upstream with other features, and also should still produce accurate enough readings to do proper load balancing.
  • Raised the MBClient timeout from 100ms to 250ms to consider the slow reaction of my Sensorbox/EV meters, may they occur. No idea if this actually does something in the greater picture.
  • Lowered the frequency of DSMR polls inside of the Sensorbox from every 2 seconds to 5 seconds.

Overall, all these things seem to result in a much more stable, happy modbus climate for the EVSE. Even after re-enabling the modbus TCP bridge and having HA query the SDM630 through the EVSE, the readings do not contain the weird value spikes anymore. So I'd call this success.

Now, since this touches some internals (e.g. extra task created, modbus value request loop slowed down, etc) I am a bit unsure if I should publish it as a branch yet until I've done some more testings. So I'll report back next week whether my issues came back or if it's definitively solved now. I do not have slave EVSE's nor use the load balancing feature, so maybe someone who does could test the 'improvements' in their set-up before we actually consider merging it.

@dingo35
Copy link

dingo35 commented Oct 1, 2023

Sounds great, but your third point worries me: how would these changes impact other users with "standard" sensorbox v2 firmware?

Also: the stalling of 0.2s occurs within the sensorbox with custom firmware, or within the SmartEVSE loop? If its within the sensorbox, who cares, because this is the primary and only task of the sensorbox; and if you would care, is it possible to solve this delay (it shouldnt be memory or cpu intense to get that dsmr value).

So when the dsmr freq is reduced from 2s to 5s, now the SmartEVSE reads that value every 200ms, so reading the same value 25 times?

Since the problem of "strange values" arised after I places the MQTT publish-calls in the updatecurrentdata routine, and diminished when I placed a mutex, I am looking at replacing the MQTT library with a threadsafe version, because I think that will solve the root cause of the problem.
And that would give us the opportunity to move more publish-calls to places where variables are changed (as intended by MQTT philosophy), instead of publishing every fixed time-interval.

I cannot test anything until december, and will be reluctant to merge any major changes I couldnt test myself...

@arpiecodes
Copy link

arpiecodes commented Oct 1, 2023

Sounds great, but your third point worries me: how would these changes impact other users with "standard" sensorbox v2 firmware?

It shouldn't. Since SmartEVSE is the master on the modbus, it will query the Sensorbox when it sees fit. The standard Sensorbox firmware has a wildly different way to get/parse the specific values from the energy meter (custom build, just a couple of values). It'll just respond if asked.

Also: the stalling of 0.2s occurs within the sensorbox with custom firmware, or within the SmartEVSE loop? If its within the sensorbox, who cares, because this is the primary and only task of the sensorbox; and if you would care, is it possible to solve this delay (it shouldnt be memory or cpu intense to get that dsmr value).

This has been changed in my custom ESPHome firmware, so on the Sensorbox and not on the EVSE. Changing the frequency of polling the actual data doesn't affect SmartEVSE in any way. The ESPHome version of DSMR polls and processes all of the values from the Smart Meter (not just 5), so it takes some time to complete it's job which is why it stalls the loop for 0.2s. This normally wouldn't be a problem if you use multi-threading on an ESP, but the developers of ESPHome are convinced one core is all you will ever need with ESPHome and thus give no option to actually utilise the second thread for anything (except internal stuff such as WiFi etc). So this is more an ESPHome thingy than anything else.

So when the dsmr freq is reduced from 2s to 5s, now the SmartEVSE reads that value every 200ms, so reading the same value 25 times?

That isn't the case since the SmartEVSE uses some fancy loop that queues up multiple readings and kind of iterates over them. In the original 100ms timer it states it will query the meters every 2 seconds. So using a 200ms timer would logically result in a request every 4 seconds. I suppose I could also try to have the ESPHome Sensorbox update it's values every 4 seconds, see how that fares. I think it mostly was struggling with the Modbus readouts/calls every 2 seconds while also doing a DSMR readout every 2 seconds. Sometimes coinciding and causing delays due to the stalls the DSMR component was causing when reading out it's values. They're both using Serial IO (modbus + readout) which can be blocking, so that makes sense.

But above probably doesn't do much for the strange value issue, as that seems to be happening inside of the SmartEVSE, not the Sensorbox. It may well explain the timeouts I was seeing at requests for Sensorbox values (but that'd be very specific to my own use-case).

Since the problem of "strange values" arised after I places the MQTT publish-calls in the updatecurrentdata routine, and diminished when I placed a mutex, I am looking at replacing the MQTT library with a threadsafe version, because I think that will solve the root cause of the problem.

I see. I didn't even think of this yet, sounds like the proper fix indeed.

I cannot test anything until december, and will be reluctant to merge any major changes I couldnt test myself...

Totally get that! No worries. I will be using this custom version for myself as it seems to fix my issues. I agree with you that we shouldn't merge anything that can't properly be tested.

The mentioned changes are found here btw; arpiecodes@0205b73. Not saying this is the proper solution for now or that we should merge it as such, but just to give an indication of what I've done here.

@dingo35
Copy link

dingo35 commented Oct 1, 2023

@arpiecodes I found this MQTT library that claims to be thread-safe:
https://github.com/cyijun/ESP32MQTTClient

I don't think it'll take too much effort to move the library to this one and give it a test, after removing the mutex's I placed in the code.

@fluppie
Copy link
Author

fluppie commented Oct 1, 2023

Nice, curious of the outcome. I did "discover" that the bogus values are sometimes kWh meter reading or voltage etc. So it's maybe a timing error? That it receives a register value from before or after the one it thinks it's requesting?

@dingo35
Copy link

dingo35 commented Oct 1, 2023

@fluppie That is very interesting, it supports the theory that the non-threadsafeness of the library causes the problem...

@arpiecodes
Copy link

arpiecodes commented Oct 2, 2023

Sad to report my code changes didn't completely alleviate the 'weird values' issue. They did help for the timeout/CRC modbus errors.

One thing I do not quite understand; why would the addition of the MQTT client be the issue? Since it is not really writing anything incase of EVMeter/MainsMeter being received through modbus, just reading them out (and then sending out to the MQTT broker). UpdateCurrentData is not called there if there was no received messages/commands over MQTT. Correct me if I'm wrong.

I do see the issue when you have multiple threads triggering the UpdateCurrent data, but then still it's weird it's only happening to modbus received values. Wouldn't logically the mutex be placed on the modbus calls/logic instead?

To me it'd make perfect sense if the collision would happen in the case the BridgeModbus connected client requests a value from the meter while SmartEVSE also requests it at the same time (or any situation where multiple requests are done for whatever reason). I'd imagine that to be a very weird situation for the meter to handle and it would probably cause issues. This gets supported by the observation that it only seems to happen (for me at least) while having the ModbusBridge in use reading out the same meter. I suppose because I lowered the interval for the SmartEVSE readouts from 2s to 4s, it made the issue less frequent, but didn't fully solve it.

@dingo35
Copy link

dingo35 commented Oct 2, 2023

The modbus logic (and protocol) is supposed to be thread safe; in the protocol the master sends data requests (through a single routine that "rotates" all the different meters/functions), and the (single) receiving routine sorts them out. So the only collisions would be when the "rotating sending routine" is called before the last call was finished. You took care of that possibility by putting that in a 200ms loop.

Also, AFAIK the problem only arises with the MQTT interface, not with the REST API.
And then it only appeared when I put the MQTT publish current data call in the updatecurrents routine.

So in my view the strange values have to do with the MQTT library.
Timeouts and CRC errors on the modbus would result in not updating the data requested, NOT in invalid data.
So reducing timeouts and CRC errors is always a good thing, but IMHO another subject.

@arpiecodes
Copy link

arpiecodes commented Oct 2, 2023

The modbus logic (and protocol) is supposed to be thread safe; in the protocol the master sends data requests (through a single routine that "rotates" all the different meters/functions), and the (single) receiving routine sorts them out. So the only collisions would be when the "rotating sending routine" is called before the last call was finished.

I see how it's thread safe for sending/receiving parts, and the part of SmartEVSE requesting those values by itself. But; what does the ModbusBridge have to bring to the table here? It's not part of that routine rotation method inside of the SmarEVSE, but requests values on it's own behalf (as requested by its clients). The single routine inside of the calls made by SmartEVSE itself won't help there.

Also, AFAIK the problem only arises with the MQTT interface, not with the REST API.

How did you test/verify this? MQTT is obviously very easy to log values and see the spikes as they occur. Through API it's probably a lot harder to catch them (but I still saw them happen there as well - just didn't try with MQTT logic disabled/removed).

@dingo35
Copy link

dingo35 commented Oct 2, 2023

True! (as to the bridge).

REST API: I stand corrected, I didnt know strange values were detected there too!

@fluppie
Copy link
Author

fluppie commented Oct 2, 2023

Here you can see voltage being logged as current. Doesn't happen often, only a few times per week. But I'm polling "only" every 15s instead of the SmartEVSE every two seconds or so.

afbeelding

@arpiecodes
Copy link

arpiecodes commented Oct 2, 2023

Screenshot 2023-10-02 at 17 27 57

Interesting to see in my case it's always the value 2387W, which seems to (in this case) match the total KWh charged since reset;

Screenshot 2023-10-02 at 17 33 29

EDIT: Yep, I also confirmed the earlier spikes are showing 2386W with contactors closed and KWh since reset being 2386.x.

@dingo35
Copy link

dingo35 commented Dec 13, 2023

I found a threadsafe MQTT library, that should/would solve the strange outlier values on the API. It doesn't use the PubSubClient underlying library, but another, ESP-IDF library that looks a lot more reliable, although it is pretty expensive in flash ram usage:
threadsafe_mqtt.zip

@arpiecodes @fluppie Could you test whether this solves /diminishes the problem?

@dingo35
Copy link

dingo35 commented Dec 13, 2023

Ok Scatman_II on tweakers reports still problems, this is a version on the old library where the current-publishments are synchronized with the other publishments:
publish_synced.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants