From aa9888800edb1eb506cab941d965b0a6f8a34806 Mon Sep 17 00:00:00 2001 From: Timothy Allen Date: Sat, 10 Oct 2026 09:03:33 +0200 Subject: [PATCH] Report EcoFlow power and temperature as floats River 2 reported total power and temperature as integers. River 3 reported temperature as an integer. InfluxDB keeps one field type for each measurement, so it rejected these points when another device wrote floats to the same measurement. --- bmspy/ecoflow_river2.py | 8 +++++--- bmspy/ecoflow_river3.py | 1 + tests/test_backend_modules.py | 21 +++++++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/bmspy/ecoflow_river2.py b/bmspy/ecoflow_river2.py index f6f4e95..02ae93e 100644 --- a/bmspy/ecoflow_river2.py +++ b/bmspy/ecoflow_river2.py @@ -338,8 +338,10 @@ class River2Decoder: if src == 0x02: # Total device power, not just battery power. charge_ratio(values["soc"], priority=1) - scalar("ef_input_power_watts", "Total Input Power", values["watts_in_sum"], "W") - scalar("ef_output_power_watts", "Total Output Power", values["watts_out_sum"], "W") + # Float, as on River 3: one measurement must keep one type, or + # InfluxDB rejects the other backend's points. + scalar("ef_input_power_watts", "Total Input Power", float(values["watts_in_sum"]), "W") + scalar("ef_output_power_watts", "Total Output Power", float(values["watts_out_sum"]), "W") remaining("ef_remaining_time_minutes", "Remaining Time", values["remain_time"]) elif cmd_id == 0x02: # EMS has separate charge/discharge estimates. if "f32_lcd_show_soc" in values: @@ -352,7 +354,7 @@ class River2Decoder: charge_ratio(values["f32_show_soc"], priority=3) else: charge_ratio(values["soc"], priority=1) - temp = values["temp"] + temp = float(values["temp"]) # Float, as from the JBD sensors. snapshot.bms_temperature_celsius = BMSMultiField( help="Battery Temperature", label="sensor", raw_values={1: temp}, values={1: str(temp)}, units="°C", diff --git a/bmspy/ecoflow_river3.py b/bmspy/ecoflow_river3.py index e4f9d34..f182ffd 100644 --- a/bmspy/ecoflow_river3.py +++ b/bmspy/ecoflow_river3.py @@ -305,6 +305,7 @@ class River3Decoder: for source, priority in (("cms_batt_temp", 1), ("bms_max_cell_temp", 2)): temp = values.get(source) if temp is not None and priority >= self._river3_temp_priority: + temp = float(temp) # Float, as from the JBD sensors. snapshot.bms_temperature_celsius = BMSMultiField( help="Battery Temperature", label="sensor", raw_values={1: temp}, values={1: str(temp)}, units="°C", diff --git a/tests/test_backend_modules.py b/tests/test_backend_modules.py index b4d81f1..fe14b73 100644 --- a/tests/test_backend_modules.py +++ b/tests/test_backend_modules.py @@ -131,6 +131,27 @@ def test_measurement_priorities_are_per_instance_and_reset_per_connection( assert value(snapshot) == low +@pytest.mark.parametrize("decoder_type,packets", [ + (ecoflow_river2.River2Decoder, [PD_PACKET, (3, 0x20, 0x32, bytes(20) + b"\x1c")]), + (ecoflow_river3.River3Decoder, [ + CELL_TEMP_PACKET, (2, 0xFE, 0x15, b"\x1d" + struct.pack("