From bd7e4b49208111644ff20c99e883c76fa95725f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C5=ABnas=20Bunokas?= Date: Fri, 5 Jan 2024 16:09:40 +0200 Subject: [PATCH] Wifi power saving mode turned off. (#2) Added custom setting for float decimal digits and appropriate code to handle float/int/non-numeric values. mqtt.yaml for HASS configuration. Amended readme a bit --- README.md | 8 +- assets/mqtt.yaml | 229 +++++++++++++++++++++++++++++++++++++++++ assets/p1_sensors.yaml | 120 --------------------- esp32_p1meter.ino | 3 +- read_p1.ino | 21 ++-- settings.h | 4 + utils.ino | 6 +- 7 files changed, 261 insertions(+), 130 deletions(-) create mode 100644 assets/mqtt.yaml delete mode 100644 assets/p1_sensors.yaml diff --git a/README.md b/README.md index 6e95f6b..b4fd932 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Setting up your Arduino IDE: - Write to your device via USB the first time, you can do it OTA all times thereafter. ### Circuit diagram -I have used the RX02 pin on the ESP32 to still use the USB port on devkit for debugging your ESP32. You could use any other pin however if you use standard RX and try debugging using USB, conflicts will happen. +I have used the RX02 pin on the ESP32 to still use the USB port on devkit for debugging your ESP32. You could use any other pin however if you use standard RX and try debugging using USB, conflicts will happen. Connect the ESP32 to an RJ12 cable/connector following the diagram. | P1 pin | ESP32 Pin | @@ -148,6 +148,10 @@ p1_meter/sensor/magnitude_of_last_voltage_swell_in_phase_l3 All the metrics you need are easily added in `DSMR_MAP` variable in `dsmr_map.h` file. With the DEBUG mode it's possible to see all the topics you add/create in the serial monitor. Also, it's possible to configure topic structure by changing `MQTT_ROOT_TOPIC` value in `settings.h` file. There is additional TEST mode to try your setup with test telegram and actual MQTT message send while your adapter is not connected to P1 port. EMAIL_DEBUGGING is used to send debug messages to any email, e.g. GMail address. This is might be usefull to trace what's going on when device is connected to P1 port and actual debugging using USB port is impossible. + ### Home Assistant Configuration -Use this [example](https://raw.githubusercontent.com/daniel-jong/esp8266_p1meter/master/assets/p1_sensors.yaml) for home assistant's `sensor.yaml` +Use this [example](assets/mqtt.yaml) for home assistant's `mqtt.yaml` which must be included in main `configuration.yaml` as follows: +```yaml +mqtt: !include mqtt.yaml +``` diff --git a/assets/mqtt.yaml b/assets/mqtt.yaml new file mode 100644 index 0000000..662f139 --- /dev/null +++ b/assets/mqtt.yaml @@ -0,0 +1,229 @@ +# Sensors for esp32_p1meter to be used in Home Assistant +# In configuration.yaml file add following line to make sensors appear in HA: +# mqtt: !include mqtt.yaml +sensor: + - name: P1 Meter Clock Raw + unique_id: p1_meter_clock_raw + state_topic: "p1_meter/sensor/clock" + icon: "mdi:clock" + - name: P1 Meter Clock Timestamp + unique_id: p1_meter_clock_timestamp + state_topic: "p1_meter/sensor/clock" + value_template: > + {{strptime(value | regex_findall_index("\d*"), '%y%m%d%H%M%S') | as_timestamp}} + - name: P1 Meter Clock Date and Time + unique_id: p1_meter_clock_datetime + state_topic: "p1_meter/sensor/clock" + value_template: > + {{strptime(value | regex_findall_index("\d*"), '%y%m%d%H%M%S')}} + + - name: P1 Meter Active energy import (+A) rate 1 + unique_id: p1_meter_active_energy_import_rate_1 + state_topic: "p1_meter/sensor/active_energy_import_rate_1" + device_class: "energy" + state_class: "total_increasing" + unit_of_measurement: "kWh" + suggested_display_precision: 3 + - name: P1 Meter Active energy import (+A) rate 2 + unique_id: p1_meter_active_energy_import_rate_2 + state_topic: "p1_meter/sensor/active_energy_import_rate_2" + device_class: "energy" + state_class: "total_increasing" + unit_of_measurement: "kWh" + suggested_display_precision: 3 + + - name: P1 Meter Active energy export (+A) rate 1 + unique_id: p1_meter_active_energy_export_rate_1 + state_topic: "p1_meter/sensor/active_energy_export_rate_1" + device_class: "energy" + state_class: "total_increasing" + unit_of_measurement: "kWh" + suggested_display_precision: 3 + - name: P1 Meter Active energy export (+A) rate 2 + unique_id: p1_meter_active_energy_export_rate_2 + state_topic: "p1_meter/sensor/active_energy_export_rate_2" + device_class: "energy" + state_class: "total_increasing" + unit_of_measurement: "kWh" + suggested_display_precision: 3 + + - name: P1 Meter Instantaneous voltage L1 + unique_id: p1_meter_instantaneous_voltage_l1 + state_topic: "p1_meter/sensor/instantaneous_voltage_l1" + device_class: "voltage" + state_class: "measurement" + unit_of_measurement: "kV" + - name: P1 Meter Instantaneous current L1 + unique_id: p1_meter_instantaneous_current_l1 + state_topic: "p1_meter/sensor/instantaneous_current_l1" + device_class: "current" + state_class: "measurement" + unit_of_measurement: "kA" + - name: P1 Meter Instantaneous voltage L2 + unique_id: p1_meter_instantaneous_voltage_l2 + state_topic: "p1_meter/sensor/instantaneous_voltage_l2" + device_class: "voltage" + state_class: "measurement" + unit_of_measurement: "kV" + - name: P1 Meter Instantaneous current L2 + unique_id: p1_meter_instantaneous_current_l2 + state_topic: "p1_meter/sensor/instantaneous_current_l2" + device_class: "current" + state_class: "measurement" + unit_of_measurement: "kA" + - name: P1 Meter Instantaneous voltage L3 + unique_id: p1_meter_instantaneous_voltage_l3 + state_topic: "p1_meter/sensor/instantaneous_voltage_l3" + device_class: "voltage" + state_class: "measurement" + unit_of_measurement: "kV" + - name: P1 Meter Instantaneous current L3 + unique_id: p1_meter_instantaneous_current_l3 + state_topic: "p1_meter/sensor/instantaneous_current_l3" + device_class: "current" + state_class: "measurement" + unit_of_measurement: "kA" + + - name: P1 Meter Instantaneous active power (|+A|+|-A|) + unique_id: p1_meter_instantaneous_active_power + state_topic: "p1_meter/sensor/instantaneous_active_power" + device_class: "power" + state_class: "measurement" + unit_of_measurement: "kW" + + - name: P1 Meter Instantaneous active import power (+A) in phase L1 + unique_id: p1_meter_instantaneous_active_import_power_in_phase_l1 + state_topic: "p1_meter/sensor/instantaneous_active_import_power_in_phase_l1" + device_class: "power" + state_class: "measurement" + unit_of_measurement: "kW" + - name: P1 Meter Instantaneous active import power (+A) in phase L2 + unique_id: p1_meter_instantaneous_active_import_power_in_phase_l2 + state_topic: "p1_meter/sensor/instantaneous_active_import_power_in_phase_l2" + device_class: "power" + state_class: "measurement" + unit_of_measurement: "kW" + - name: P1 Meter Instantaneous active import power (+A) in phase L3 + unique_id: p1_meter_instantaneous_active_import_power_in_phase_l3 + state_topic: "p1_meter/sensor/instantaneous_active_import_power_in_phase_l3" + device_class: "power" + state_class: "measurement" + unit_of_measurement: "kW" + + - name: P1 Meter Instantaneous active export power (-A) in phase L1 + unique_id: p1_meter_instantaneous_active_export_power_in_phase_l1 + state_topic: "p1_meter/sensor/instantaneous_active_export_power_in_phase_l1" + device_class: "power" + state_class: "measurement" + unit_of_measurement: "kW" + - name: P1 Meter Instantaneous active export power (-A) in phase L2 + unique_id: p1_meter_instantaneous_active_export_power_in_phase_l2 + state_topic: "p1_meter/sensor/instantaneous_active_export_power_in_phase_l2" + device_class: "power" + state_class: "measurement" + unit_of_measurement: "kW" + - name: P1 Meter Instantaneous active export power (-A) in phase L3 + unique_id: p1_meter_instantaneous_active_export_power_in_phase_l3 + state_topic: "p1_meter/sensor/instantaneous_active_export_power_in_phase_l3" + device_class: "power" + state_class: "measurement" + unit_of_measurement: "kW" + + - name: P1 Meter Instantaneous apparent import power (+VA) + unique_id: p1_meter_instantaneous_apparent_import_power + state_topic: "p1_meter/sensor/instantaneous_apparent_import_power" + device_class: "apparent_power" + state_class: "measurement" + unit_of_measurement: "kVA" + - name: P1 Meter Instantaneous apparent import power (+VA) in phase L1 + unique_id: p1_meter_instantaneous_apparent_import_power_in_phase_l1 + state_topic: "p1_meter/sensor/instantaneous_apparent_import_power_in_phase_l1" + device_class: "apparent_power" + state_class: "measurement" + unit_of_measurement: "kVA" + - name: P1 Meter Instantaneous apparent import power (+VA) in phase L2 + unique_id: p1_meter_instantaneous_apparent_import_power_in_phase_l2 + state_topic: "p1_meter/sensor/instantaneous_apparent_import_power_in_phase_l2" + device_class: "apparent_power" + state_class: "measurement" + unit_of_measurement: "kVA" + - name: P1 Meter Instantaneous apparent import power (+VA) in phase L3 + unique_id: p1_meter_instantaneous_apparent_import_power_in_phase_l3 + state_topic: "p1_meter/sensor/instantaneous_apparent_import_power_in_phase_l3" + device_class: "apparent_power" + state_class: "measurement" + unit_of_measurement: "kVA" + + - name: P1 Meter Instantaneous apparent export power (-VA) + unique_id: p1_meter_instantaneous_apparent_export_power + state_topic: "p1_meter/sensor/instantaneous_apparent_export_power" + device_class: "apparent_power" + state_class: "measurement" + unit_of_measurement: "kVA" + - name: P1 Meter Instantaneous apparent export power (-VA) in phase L1 + unique_id: p1_meter_instantaneous_apparent_export_power_in_phase_l1 + state_topic: "p1_meter/sensor/instantaneous_apparent_export_power_in_phase_l1" + device_class: "apparent_power" + state_class: "measurement" + unit_of_measurement: "kVA" + - name: P1 Meter Instantaneous apparent export power (-VA) in phase L2 + unique_id: p1_meter_instantaneous_apparent_export_power_in_phase_l2 + state_topic: "p1_meter/sensor/instantaneous_apparent_export_power_in_phase_l2" + device_class: "apparent_power" + state_class: "measurement" + unit_of_measurement: "kVA" + - name: P1 Meter Instantaneous apparent export power (-VA) in phase L3 + unique_id: p1_meter_instantaneous_apparent_export_power_in_phase_l3 + state_topic: "p1_meter/sensor/instantaneous_apparent_export_power_in_phase_l3" + device_class: "apparent_power" + state_class: "measurement" + unit_of_measurement: "kVA" + + - name: P1 Meter Instantaneous Power factor (+A/+VA) + unique_id: p1_meter_instantaneous_power_factor + state_topic: "p1_meter/sensor/instantaneous_power_factor" + device_class: "power_factor" + state_class: "measurement" + - name: P1 Meter Instantaneous power factor in phase L1 + unique_id: p1_meter_instantaneous_power_factor_in_phase_l1 + state_topic: "p1_meter/sensor/instantaneous_power_factor_in_phase_l1" + device_class: "power_factor" + state_class: "measurement" + - name: P1 Meter Instantaneous power factor in phase L2 + unique_id: p1_meter_instantaneous_power_factor_in_phase_l2 + state_topic: "p1_meter/sensor/instantaneous_power_factor_in_phase_l2" + device_class: "power_factor" + state_class: "measurement" + - name: P1 Meter Instantaneous power factor in phase L3 + unique_id: p1_meter_instantaneous_power_factor_in_phase_l3 + state_topic: "p1_meter/sensor/instantaneous_power_factor_in_phase_l3" + device_class: "power_factor" + state_class: "measurement" + - name: P1 Meter Minimum Power factor (+A/+VA) + unique_id: p1_meter_minimum_power_factor + state_topic: "p1_meter/sensor/minimum_power_factor" + device_class: "power_factor" + state_class: "measurement" + + - name: P1 Meter Number of power failures in any phase + unique_id: p1_meter_number_of_power_failures_in_any_phase + state_topic: "p1_meter/sensor/number_of_power_failures_in_any_phase" + state_class: "total_increasing" + - name: P1 Meter Duration of last voltage sag in phase L1 + unique_id: p1_meter_duration_of_last_voltage_sag_in_phase_l1 + state_topic: "p1_meter/sensor/duration_of_last_voltage_sag_in_phase_l1" + device_class: "duration" + state_class: "measurement" + unit_of_measurement: "s" + - name: P1 Meter Duration of last voltage sag in phase L2 + unique_id: p1_meter_duration_of_last_voltage_sag_in_phase_l2 + state_topic: "p1_meter/sensor/duration_of_last_voltage_sag_in_phase_l2" + device_class: "duration" + state_class: "measurement" + unit_of_measurement: "s" + - name: P1 Meter Duration of last voltage sag in phase L3 + unique_id: p1_meter_duration_of_last_voltage_sag_in_phase_l3 + state_topic: "p1_meter/sensor/duration_of_last_voltage_sag_in_phase_l3" + device_class: "duration" + state_class: "measurement" + unit_of_measurement: "s" diff --git a/assets/p1_sensors.yaml b/assets/p1_sensors.yaml deleted file mode 100644 index 4978320..0000000 --- a/assets/p1_sensors.yaml +++ /dev/null @@ -1,120 +0,0 @@ -# Sensors for esp32_p1meter to be used in Home Assistant - -- platform: mqtt - name: P1 Consumption Low Tariff - unit_of_measurement: "kWh" - state_topic: "sensors/power/p1meter/consumption_low_tarif" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 Consumption High Tariff - unit_of_measurement: "kWh" - state_topic: "sensors/power/p1meter/consumption_high_tarif" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 Return Delivery High Tariff - unit_of_measurement: "kWh" - state_topic: "sensors/power/p1meter/returndelivery_high_tarif" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 Return Delivery Low Tariff - unit_of_measurement: "kWh" - state_topic: "sensors/power/p1meter/returndelivery_low_tarif" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 Actual Power Consumption - unit_of_measurement: "kW" - state_topic: "sensors/power/p1meter/actual_consumption" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 Actual Return Delivery - unit_of_measurement: "kW" - state_topic: "sensors/power/p1meter/actual_received" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L1 Instant Power Usage - unit_of_measurement: "kW" - state_topic: "sensors/power/p1meter/instant_power_usage_l1" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L2 Instant Power Usage - unit_of_measurement: "kW" - state_topic: "sensors/power/p1meter/instant_power_usage_l2" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L3 Instant Power Usage - unit_of_measurement: "kW" - state_topic: "sensors/power/p1meter/instant_power_usage_l3" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L1 Instant Power Return - unit_of_measurement: "kW" - state_topic: "sensors/power/p1meter/instant_power_return_l1" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L2 Instant Power Return - unit_of_measurement: "kW" - state_topic: "sensors/power/p1meter/instant_power_return_l2" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L3 Instant Power Return - unit_of_measurement: "kW" - state_topic: "sensors/power/p1meter/instant_power_return_l3" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L1 Instant Power Current - unit_of_measurement: "A" - state_topic: "sensors/power/p1meter/instant_power_current_l1" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L2 Instant Power Current - unit_of_measurement: "A" - state_topic: "sensors/power/p1meter/instant_power_current_l2" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L3 Instant Power Current - unit_of_measurement: "A" - state_topic: "sensors/power/p1meter/instant_power_current_l3" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L1 Voltage - unit_of_measurement: "V" - state_topic: "sensors/power/p1meter/instant_voltage_l1" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L2 Voltage - unit_of_measurement: "V" - state_topic: "sensors/power/p1meter/instant_voltage_l2" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 L3 Voltage - unit_of_measurement: "V" - state_topic: "sensors/power/p1meter/instant_voltage_l3" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 Gas Usage - unit_of_measurement: "m3" - state_topic: "sensors/power/p1meter/gas_meter_m3" - value_template: "{{ value|float / 1000 }}" - -- platform: mqtt - name: P1 Actual Tariff Group - state_topic: "sensors/power/p1meter/actual_tarif_group" - diff --git a/esp32_p1meter.ino b/esp32_p1meter.ino index 8479858..a873419 100644 --- a/esp32_p1meter.ino +++ b/esp32_p1meter.ino @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -125,4 +126,4 @@ void setupOTA() { ArduinoOTA.setHostname(String(HOSTNAME).c_str()); ArduinoOTA.setPasswordHash(String(OTA_PASSWORD_HASH).c_str()); ArduinoOTA.begin(); -} +} \ No newline at end of file diff --git a/read_p1.ino b/read_p1.ino index 7b8d286..a7f19fd 100644 --- a/read_p1.ino +++ b/read_p1.ino @@ -14,13 +14,20 @@ unsigned int crc16(unsigned int crc, unsigned char *buf, int len) { return crc; } -bool isNumber(char *res, int len) { +short getValueType(char *res, int len) { + short dotsFound = 0; for (int i = 0; i < len; i++) { if (((res[i] < '0') || (res[i] > '9')) && (res[i] != '.' && res[i] != 0)) { - return false; + return -1; // non-numeric } + if (res[i] == '.') { + dotsFound++; + } + } + if (dotsFound > 1) { + return -1; // more than 1 dot means something weird, not number for sure } - return true; + return dotsFound; // 1 - float/double, 0 - integer } int findCharInArrayRev(char array[], char c, int len) { @@ -44,8 +51,11 @@ String getValue(char *buffer, int maxlen, char startchar, char endchar) { memset(res, 0, sizeof(res)); if (strncpy(res, buffer + s + 1, l)) { - if (isNumber(res, l)) - return String((endchar == VALUE_END_CHAR ? VALUE_NUMERIC_MULTIPLIER : 1) * atof(res)); + short numType = getValueType(res, l); + if (numType == 1) // float or double + return String((endchar == VALUE_END_CHAR ? VALUE_NUMERIC_MULTIPLIER : 1) * atof(res), VALUE_FLOAT_DECIMAL_PLACES); + else if (numType == 0) // integer + return String((endchar == VALUE_END_CHAR ? VALUE_NUMERIC_MULTIPLIER : 1) * atoi(res)); else return String(res); } @@ -140,4 +150,3 @@ bool readP1Serial() { return false; } - diff --git a/settings.h b/settings.h index 36a110e..8e8de80 100644 --- a/settings.h +++ b/settings.h @@ -59,6 +59,10 @@ String emailMessageDump; // if your P1 values with units need to be multiplied by any multiplier, specify it here long VALUE_NUMERIC_MULTIPLIER = 1; +// Decimal places for float values, by default it's 2 +// Integers are handled automatically and no decimals are used +unsigned short VALUE_FLOAT_DECIMAL_PLACES = 3; + // Nothing to change below - globals to make it all work as simple as possible char telegram[P1_MAXLINELENGTH]; diff --git a/utils.ino b/utils.ino index e912c6e..41d39d2 100644 --- a/utils.ino +++ b/utils.ino @@ -12,8 +12,12 @@ void blinkLed(int numberOfBlinks, int msBetweenBlinks) { void makeSureWiFiConnected(bool setupMode) { if (setupMode) { + //turn WiFi power saving mode off + esp_wifi_set_ps(WIFI_PS_NONE); + WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASS); + delay(3000); } @@ -74,4 +78,4 @@ void debug(String msg) { #endif #endif ; -} +} \ No newline at end of file