From 9349e6e5d053b28fa668240d815feca8bc734874 Mon Sep 17 00:00:00 2001 From: Marc Plogas Date: Wed, 18 Sep 2024 23:42:20 +0200 Subject: [PATCH] fixes to conversion and cleanup --- .../Discovery/DiscoveryPublishService.cs | 6 +- .../Mapping/SensorBuilder.cs | 237 +++++++++--------- .../Mapping/SensorBuilderLogic.cs | 45 +++- 3 files changed, 155 insertions(+), 133 deletions(-) diff --git a/src/Ecowitt.Controller/Discovery/DiscoveryPublishService.cs b/src/Ecowitt.Controller/Discovery/DiscoveryPublishService.cs index 41e1b21..d83e28b 100644 --- a/src/Ecowitt.Controller/Discovery/DiscoveryPublishService.cs +++ b/src/Ecowitt.Controller/Discovery/DiscoveryPublishService.cs @@ -116,7 +116,7 @@ private async Task PublishSubdeviceSwitchDiscovery(Gateway gw, Ecowitt.Controlle { var device = DiscoveryBuilder.BuildDevice(subdevice.Nickname, subdevice.Model.ToString(), "Ecowitt", subdevice.Model.ToString(), subdevice.Version.ToString(), DiscoveryBuilder.BuildIdentifier(gw.Name)); var id = DiscoveryBuilder.BuildIdentifier(subdevice.Nickname, "switch"); - var statetopic = $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttSubdeviceTopic(gw.Name, subdevice.Id.ToString())}/diag/status"; + var statetopic = $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttSubdeviceTopic(gw.Name, subdevice.Id.ToString())}/diag/running"; var valueTemplate = "{% if (value_json.value == true) -%} ON {%- else -%} OFF {%- endif %}"; var cmdTopic = $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttSubdeviceHACommandTopic(gw.Name, subdevice.Id.ToString())}"; @@ -130,7 +130,7 @@ private async Task PublishSensorDiscovery(Gateway gw, ISensor sensor) { var device = gw.Model == null ? DiscoveryBuilder.BuildDevice(gw.Name) : DiscoveryBuilder.BuildDevice(gw.Name, gw.Model, "Ecowitt", gw.Model, gw.StationType ?? "unknown"); - var statetopic = sensor.SensorCategory == SensorCategory.Diagnostic ? $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttGatewayDiagnosticTopic(gw.Name, sensor.Name)}" : $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttGatewaySensorTopic(gw.Name, sensor.Name)}"; + var statetopic = sensor.SensorCategory == SensorCategory.Diagnostic ? $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttGatewayDiagnosticTopic(gw.Name, sensor.Alias)}" : $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttGatewaySensorTopic(gw.Name, sensor.Alias)}"; var availabilityTopic = $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttGatewayTopic(gw.Name)}/availability"; await PublishSensorDiscovery(device, sensor, statetopic, availabilityTopic); } @@ -138,7 +138,7 @@ private async Task PublishSensorDiscovery(Gateway gw, ISensor sensor) private async Task PublishSensorDiscovery(Gateway gw, Ecowitt.Controller.Model.Subdevice subdevice, ISensor sensor) { var device = DiscoveryBuilder.BuildDevice(subdevice.Nickname, subdevice.Model.ToString(), "Ecowitt", subdevice.Model.ToString(), subdevice.Version.ToString(), DiscoveryBuilder.BuildIdentifier(gw.Name)); - var statetopic = sensor.SensorCategory == SensorCategory.Diagnostic ? $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttSubdeviceDiagnosticTopic(gw.Name, subdevice.Id.ToString(), sensor.Name)}" : $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttSubdeviceSensorTopic(gw.Name, subdevice.Id.ToString(), sensor.Name)}"; + var statetopic = sensor.SensorCategory == SensorCategory.Diagnostic ? $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttSubdeviceDiagnosticTopic(gw.Name, subdevice.Id.ToString(), sensor.Alias)}" : $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttSubdeviceSensorTopic(gw.Name, subdevice.Id.ToString(), sensor.Alias)}"; var availabilityTopic = $"{_mqttOptions.BaseTopic}/{Helper.BuildMqttSubdeviceTopic(gw.Name, subdevice.Id.ToString())}/availability"; await PublishSensorDiscovery(device, sensor, statetopic, availabilityTopic); } diff --git a/src/Ecowitt.Controller/Mapping/SensorBuilder.cs b/src/Ecowitt.Controller/Mapping/SensorBuilder.cs index 2616cc9..630ddcd 100644 --- a/src/Ecowitt.Controller/Mapping/SensorBuilder.cs +++ b/src/Ecowitt.Controller/Mapping/SensorBuilder.cs @@ -1,115 +1,112 @@ using Ecowitt.Controller.Model; using Serilog; +/* all currently available sensors. their naming scheme is not consistent, so we have to map them manually +PASSKEY +stationtype +runtime +dateutc +tempinf +humidityin +baromrelin +baromabsin +tempf +humidity +winddir +windspeedmph +windgustmph +maxdailygust +solarradiation +uv +rainratein +eventrainin +hourlyrainin +dailyrainin +weeklyrainin +monthlyrainin +yearlyrainin +totalrainin +rrain_piezo +erain_piezo +hrain_piezo +drain_piezo +wrain_piezo +mrain_piezo +yrain_piezo +ws90cap_volt +ws90_ver +tempf1,….,,tempf8 +humidity1,….,humidity8 +soilmoisture1,….., soilmoisture8 +soilad1,…., soilad8 +pm25_ch1, …., pm25_ch4 +pm25_avg_24h_ch1,…..,pm25_avg_24h_ch4 +tf_co2 +humi_co2 +pm1_co2 +pm1_24h_co2 +pm25_co2 +pm25_24h_co2 +pm4_co2 +pm4_24h_co2 +pm10_co2 +pm10_24h_co2 +co2 +co2_24h +lightning_num +lightning +lightning_time +leak_ch1 …., leak_ch4 +tf_ch1, …., tf_ch8 +leafwetness_ch1,…, leafwetness_ch8 +console_batt +wh65batt +wh80batt +wh26batt +batt1,….,batt8 +soilbatt1,…,soilbatt8 +pm25batt1, …, pm25batt4 +wh57batt +leakbatt1, …,leakbatt4 +tf_batt1, …, tf_batt8 +co2_batt +leaf_batt1, …, leaf_batt8 +wh90batt +freq +model +interval +ac_status +warning +always_on +val_type +val +run_time +rssi +gw_rssi +timeutc +publish_time +ac_action +ac_running +plan_status +elect_total +happen_elect +realtime_power +ac_voltage +ac_current +water_status +water_action +water_running +water_total +happen_water +flow_velocity +water_temp +wfc01batt +*/ + namespace Ecowitt.Controller.Mapping { public partial class SensorBuilder { - /* all currently available sensors. their naming scheme is not consistent, so we have to map them manually - | sensor name | - | -------------- | - | PASSKEY | - | stationtype | - | runtime | - | dateutc | - | tempinf | - | humidityin | - | baromrelin | - | baromabsin | - | tempf | - | humidity | - | winddir | - | windspeedmph | - | windgustmph | - | maxdailygust | - | solarradiation | - | uv | - | rainratein | - | eventrainin | - | hourlyrainin | - | dailyrainin | - | weeklyrainin | - | monthlyrainin | - | yearlyrainin | - | totalrainin | - | rrain_piezo | - | erain_piezo | - | hrain_piezo | - | drain_piezo | - | wrain_piezo | - | mrain_piezo | - | yrain_piezo | - | ws90cap_volt | - | ws90_ver | - | tempf1,….,,tempf8 | - | humidity1,….,humidity8 | - | soilmoisture1,….., soilmoisture8 | - | soilad1,…., soilad8 | - | pm25_ch1, …., pm25_ch4 | - | pm25_avg_24h_ch1,…..,pm25_avg_24h_ch4 | - | tf_co2 | - | humi_co2 | - | pm1_co2 | - | pm1_24h_co2 | - | pm25_co2 | - | pm25_24h_co2 | - | pm4_co2 | - | pm4_24h_co2 | - | pm10_co2 | - | pm10_24h_co2 | - | co2 | - | co2_24h | - | lightning_num | - | lightning | - | lightning_time | - | leak_ch1 …., leak_ch4 | - | tf_ch1, …., tf_ch8 | - | leafwetness_ch1,…, leafwetness_ch8 | - | console_batt | - | wh65batt | - | wh80batt | - | wh26batt | - | batt1,….,batt8 | - | soilbatt1,…,soilbatt8 | - | pm25batt1, …, pm25batt4 | - | wh57batt | - | leakbatt1, …,leakbatt4 | - | tf_batt1, …, tf_batt8 | - | co2_batt | - | leaf_batt1, …, leaf_batt8 | - | wh90batt | - | freq | - | model | - | interval | - | ac_status | - | warning | - | always_on | - | val_type | - | val | - | run_time | - | rssi | - | gw_rssi | - | timeutc | - | publish_time | - | ac_action | - | ac_running | - | plan_status | - | elect_total | - | happen_elect | - | realtime_power | - | ac_voltage | - | ac_current | - | water_status | - | water_action | - | water_running | - | water_total | - | happen_water | - | flow_velocity | - | water_temp | - | wfc01batt | - | ------------------------- | - */ - public static ISensor? BuildSensor(string propertyName, string propertyValue, bool isMetric = true) { switch (propertyName) @@ -275,12 +272,16 @@ public partial class SensorBuilder number = GetNumber(propertyName); return BuildIntSensor(propertyName, $"Leaf Wetness {number}", propertyValue, "%"); case "console_batt": + // maybe it's voltage, I don't have this sensor return BuildBatterySensor(propertyName, "Console Battery", propertyValue); case "wh65batt": + // maybe it's voltage, I don't have this sensor return BuildBatterySensor(propertyName, "WH65 Battery", propertyValue); case "wh80batt": + // maybe it's voltage, I don't have this sensor return BuildBatterySensor(propertyName, "WH80 Battery", propertyValue); case "wh26batt": + // maybe it's voltage, I don't have this sensor return BuildBatterySensor(propertyName, "WH26 Battery", propertyValue); case "batt1": case "batt2": @@ -290,10 +291,10 @@ public partial class SensorBuilder case "batt6": case "batt7": case "batt8": + // maybe it's voltage, I don't have this sensor number = GetNumber(propertyName); return BuildBatterySensor(propertyName, $"Battery {number}", propertyValue); - // maybe it's voltage, I don't have this sensor - //return BuildVoltageSensor(propertyName, $"Battery {number}", propertyValue, isDiag: true); + //return BuildVoltageSensor(propertyName, $"Battery {number}", propertyValue, isDiag: true); case "soilbatt1": case "soilbatt2": case "soilbatt3": @@ -308,18 +309,18 @@ public partial class SensorBuilder case "pm25batt2": case "pm25batt3": case "pm25batt4": + // maybe it's voltage, I don't have this sensor number = GetNumber(propertyName); return BuildBatterySensor(propertyName, $"PM2.5 Battery {number}", propertyValue); - // maybe it's voltage, I don't have this sensor case "wh57batt": - return BuildBatterySensor(propertyName, "WH57 Battery", propertyValue); + return BuildBatterySensor(propertyName, "WH57 Battery", propertyValue, true); case "leakbatt1": case "leakbatt2": case "leakbatt3": case "leakbatt4": + // maybe it's voltage, I don't have this sensor number = GetNumber(propertyName); return BuildBatterySensor(propertyName, $"Leak Battery {number}", propertyValue); - // maybe it's voltage, I don't have this sensor case "tf_batt1": case "tf_batt2": case "tf_batt3": @@ -328,11 +329,11 @@ public partial class SensorBuilder case "tf_batt6": case "tf_batt7": case "tf_batt8": + // maybe it's voltage, I don't have this sensor number = GetNumber(propertyName); return BuildBatterySensor(propertyName, $"Temperature Battery {number}", propertyValue); - // maybe it's voltage, I don't have this sensor case "co2_batt": - return BuildBatterySensor(propertyName, "CO2 Battery", propertyValue); + return BuildBatterySensor(propertyName, "CO2 Battery", propertyValue, true); case "leaf_batt1": case "leaf_batt2": case "leaf_batt3": @@ -341,15 +342,15 @@ public partial class SensorBuilder case "leaf_batt6": case "leaf_batt7": case "leaf_batt8": + // maybe it's voltage, I don't have this sensor number = GetNumber(propertyName); return BuildBatterySensor(propertyName, $"Leaf Battery {number}", propertyValue); - // maybe it's voltage, I don't have this sensor case "wh90batt": - return BuildBatterySensor(propertyName, "WH90 Battery", propertyValue); + return BuildVoltageSensor(propertyName, "WH90 Battery", propertyValue, true); case "ac_status": return BuildBinarySensor(propertyName, "AC Status", propertyValue); case "ac_running": - return BuildBinarySensor(propertyName, "AC Running", propertyValue); + return BuildBinarySensor(propertyName, "Running", propertyValue); case "warning": return BuildBinarySensor(propertyName, "Warning", propertyValue); case "always_on": @@ -381,7 +382,7 @@ public partial class SensorBuilder case "water_action": return BuildIntSensor(propertyName, "Water Action", propertyValue, isDiag: true); case "water_running": - return BuildBinarySensor(propertyName, "Water Running", propertyValue); + return BuildBinarySensor(propertyName, "Running", propertyValue); case "water_total": return BuildWaterConsumptionSensor(propertyName, "Total Water", propertyValue, isMetric, true); case "happen_water": @@ -390,9 +391,9 @@ public partial class SensorBuilder case "flow_velocity": return BuildWaterFlowSensor(propertyName, "Flow Velocity", propertyValue, isMetric); case "water_temp": - return BuildTemperatureSensor(propertyName, "Water Temperature", propertyValue, isMetric); + return BuildTemperatureSensor(propertyName, "Water Temperature", propertyValue, isMetric, true); case "wfc01batt": - return BuildBatterySensor(propertyName, "WFC01 Battery", propertyValue); + return BuildBatterySensor(propertyName, "WFC01 Battery", propertyValue, true); case "heap": return BuildIntSensor(propertyName, "Gateway Heap", propertyValue, "byte", SensorType.None); case "PASSKEY": diff --git a/src/Ecowitt.Controller/Mapping/SensorBuilderLogic.cs b/src/Ecowitt.Controller/Mapping/SensorBuilderLogic.cs index e446329..ab5e2aa 100644 --- a/src/Ecowitt.Controller/Mapping/SensorBuilderLogic.cs +++ b/src/Ecowitt.Controller/Mapping/SensorBuilderLogic.cs @@ -52,15 +52,28 @@ public partial class SensorBuilder private static Sensor? BuildBinarySensor(string propertyName, string alias, string propertyValue, bool isDiag = true) { - return bool.TryParse(propertyValue, out var value) - ? new Sensor(propertyName, alias, value, sensorClass: SensorClass.BinarySensor, sensorCategory: isDiag ? SensorCategory.Diagnostic : SensorCategory.Config) - : null; - } - - private static Sensor? BuildBatterySensor(string propertyName, string alias, string propertyValue) + bool value; + switch (propertyValue) + { + case "0": + case "false": + value = false; + break; + case "1": + case "true": + value = true; + break; + default: + return null; + } + + return new Sensor(propertyName, alias, value, sensorClass: SensorClass.BinarySensor, sensorCategory: isDiag ? SensorCategory.Diagnostic : SensorCategory.Config); + } + + private static Sensor? BuildBatterySensor(string propertyName, string alias, string propertyValue, bool withMultiplier = false ) { return int.TryParse(propertyValue, out var value) - ? new Sensor(propertyName, alias, value, "%", SensorType.Battery, sensorCategory: SensorCategory.Diagnostic) + ? new Sensor(propertyName, alias, withMultiplier ? value * 20 : value, "%", SensorType.Battery, sensorCategory: SensorCategory.Diagnostic) : null; } @@ -120,12 +133,20 @@ public partial class SensorBuilder : null; } - private static Sensor? BuildTemperatureSensor(string propertyName, string alias, string propertyValue, - bool isMetric) + private static Sensor? BuildTemperatureSensor(string propertyName, string alias, string propertyValue, bool isMetric, bool startMetric = false) { - return double.TryParse(propertyValue, out var value) - ? new Sensor(propertyName, alias, isMetric ? F2C(value) : value, isMetric ? "°C" : "F", SensorType.Temperature) - : null; + if (double.TryParse(propertyValue, out var value)) + { + var unit = isMetric ? "°C" : "F"; + if (startMetric != isMetric) + { + value = startMetric ? C2F(value) : F2C(value); + } + + return new Sensor(propertyName, alias, value, unit, SensorType.Temperature); + } + + return null; } private static Sensor? BuildDoubleSensor(string propertyName, string alias, string propertyValue, string unit = "", SensorType type = SensorType.None, bool isDiag = false)