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.
This commit is contained in:
tim
2026-10-10 09:03:33 +02:00
parent f36bb2510c
commit aa9888800e
3 changed files with 27 additions and 3 deletions
+5 -3
View File
@@ -338,8 +338,10 @@ class River2Decoder:
if src == 0x02: # Total device power, not just battery power. if src == 0x02: # Total device power, not just battery power.
charge_ratio(values["soc"], priority=1) charge_ratio(values["soc"], priority=1)
scalar("ef_input_power_watts", "Total Input Power", values["watts_in_sum"], "W") # Float, as on River 3: one measurement must keep one type, or
scalar("ef_output_power_watts", "Total Output Power", values["watts_out_sum"], "W") # 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"]) remaining("ef_remaining_time_minutes", "Remaining Time", values["remain_time"])
elif cmd_id == 0x02: # EMS has separate charge/discharge estimates. elif cmd_id == 0x02: # EMS has separate charge/discharge estimates.
if "f32_lcd_show_soc" in values: if "f32_lcd_show_soc" in values:
@@ -352,7 +354,7 @@ class River2Decoder:
charge_ratio(values["f32_show_soc"], priority=3) charge_ratio(values["f32_show_soc"], priority=3)
else: else:
charge_ratio(values["soc"], priority=1) charge_ratio(values["soc"], priority=1)
temp = values["temp"] temp = float(values["temp"]) # Float, as from the JBD sensors.
snapshot.bms_temperature_celsius = BMSMultiField( snapshot.bms_temperature_celsius = BMSMultiField(
help="Battery Temperature", label="sensor", help="Battery Temperature", label="sensor",
raw_values={1: temp}, values={1: str(temp)}, units="°C", raw_values={1: temp}, values={1: str(temp)}, units="°C",
+1
View File
@@ -305,6 +305,7 @@ class River3Decoder:
for source, priority in (("cms_batt_temp", 1), ("bms_max_cell_temp", 2)): for source, priority in (("cms_batt_temp", 1), ("bms_max_cell_temp", 2)):
temp = values.get(source) temp = values.get(source)
if temp is not None and priority >= self._river3_temp_priority: 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( snapshot.bms_temperature_celsius = BMSMultiField(
help="Battery Temperature", label="sensor", help="Battery Temperature", label="sensor",
raw_values={1: temp}, values={1: str(temp)}, units="°C", raw_values={1: temp}, values={1: str(temp)}, units="°C",
+21
View File
@@ -131,6 +131,27 @@ def test_measurement_priorities_are_per_instance_and_reset_per_connection(
assert value(snapshot) == low 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("<f", 244) + b"\x25" + struct.pack("<f", 39)),
]),
], ids=["river2", "river3"])
def test_shared_power_and_temperature_measurements_are_floats(decoder_type, packets):
# InfluxDB keeps one type per measurement. The JBD temperatures are floats,
# so an integer from either EcoFlow model would be rejected in a shared bucket.
snapshot = EcoFlowSnapshot()
decoder = decoder_type()
for packet in packets:
decoder.update(snapshot, *packet)
values = [
snapshot.ef_input_power_watts.raw_value,
snapshot.ef_output_power_watts.raw_value,
*snapshot.bms_temperature_celsius.raw_values.values(),
]
assert [type(value) for value in values] == [float, float, float]
def test_snapshot_keeps_diagnostic_packets_and_json_round_trip(): def test_snapshot_keeps_diagnostic_packets_and_json_round_trip():
from bmspy.classes import UPS from bmspy.classes import UPS