[fineoffsetweatherstation] Fix false low battery for voltage sensors on HTTP API (#21000)

* [fineoffsetweatherstation] Fix false low battery for voltage sensors on HTTP API

Signed-off-by: Andreas Berger <andreas@berger-freelancer.com>
This commit is contained in:
Andreas Berger
2026-06-19 10:31:38 +02:00
committed by GitHub
parent 4270356dee
commit a86adc9705
4 changed files with 35 additions and 5 deletions
@@ -50,13 +50,26 @@ public enum Sensor {
WN20(LOW_HIGH),
WN38(VOLTAGE_FINE_STEPS);
private final BatteryStatus.Type batteryStatusTpe;
private final BatteryStatus.Type batteryStatusType;
Sensor(BatteryStatus.Type batteryStatusTpe) {
this.batteryStatusTpe = batteryStatusTpe;
Sensor(BatteryStatus.Type batteryStatusType) {
this.batteryStatusType = batteryStatusType;
}
public BatteryStatus getBatteryStatus(byte data) {
return new BatteryStatus(batteryStatusTpe, data);
return new BatteryStatus(batteryStatusType, data);
}
/**
* Interprets the battery field as reported by the Ecowitt HTTP API. Unlike the binary protocol, the HTTP API
* reports the battery of voltage-based sensors already as a 0-5 level (5 = full) rather than a raw voltage, so
* those are read as {@link BatteryStatus.Type#LEVEL}; all other sensor types share the binary encoding.
*/
public BatteryStatus getHttpBatteryStatus(byte data) {
BatteryStatus.Type type = switch (batteryStatusType) {
case VOLTAGE_BROAD_STEPS, VOLTAGE_FINE_STEPS -> LEVEL;
default -> batteryStatusType;
};
return new BatteryStatus(type, data);
}
}
@@ -138,6 +138,10 @@ public enum SensorGatewayBinding {
return sensor.getBatteryStatus(data);
}
public BatteryStatus getHttpBatteryStatus(byte data) {
return sensor.getHttpBatteryStatus(data);
}
public Sensor getSensor() {
return sensor;
}
@@ -191,7 +191,7 @@ public class EcowittDataParser {
} catch (NumberFormatException e) {
return;
}
BatteryStatus batteryStatus = sensorGatewayBinding.getBatteryStatus((byte) parseInt(asString(obj, "batt")));
BatteryStatus batteryStatus = sensorGatewayBinding.getHttpBatteryStatus((byte) parseInt(asString(obj, "batt")));
int signal = parseInt(asString(obj, "signal"));
result.put(sensorGatewayBinding, new SensorDevice(id, sensorGatewayBinding, batteryStatus, signal));
}
@@ -130,6 +130,19 @@ class EcowittDataParserTest {
new Tuple("WH25", 0xB9, 4, true));
}
@Test
void testVoltageSensorBatteryReportedAsLevel() {
// unlike the binary protocol, where the WH51 battery field is a raw voltage (val * 0.1 V), the Ecowitt HTTP
// API reports it already as a 0-5 level (5 = full). It must therefore not be misread as 0.5 V and flagged low.
Map<SensorGatewayBinding, SensorDevice> sensors = parser.parseSensors(List.of("[{\"img\":\"wh51\","
+ "\"type\":\"14\",\"name\":\"Soil moisture CH1\",\"id\":\"FBF08\",\"batt\":\"5\",\"rssi\":\"-85\","
+ "\"signal\":\"4\",\"idst\":\"1\"}]"), false);
Assertions.assertThat(sensors.values())
.extracting(device -> device.getSensorGatewayBinding().getSensor().name(),
device -> device.getBatteryStatus().isLow(), device -> device.getBatteryStatus().getLevel())
.containsExactly(new Tuple("WH51", false, 5));
}
@Test
void testSystemInfo() {
@Nullable