From d31682abf84cdd58016d6bda44a0e6e26acecc88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Z=C3=BCrcher?= Date: Tue, 11 Oct 2022 20:35:37 +0200 Subject: [PATCH 1/5] Modification for LandisGyr --- heltec-cubecell/config.h | 6 +++-- heltec-cubecell/heltec-cubecell.ino | 34 ++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/heltec-cubecell/config.h b/heltec-cubecell/config.h index 81c23c8..9195d18 100644 --- a/heltec-cubecell/config.h +++ b/heltec-cubecell/config.h @@ -27,13 +27,15 @@ // ADJUSTME: Identifier string to successful recognize the identification response from the smart meter. // Usually it's in the form of: /AAAB@xxxxxxx where AAA is the identifier string and B the max baud-rate info flag needed for the baud-switch. // Hint: set to NULL if you don't know it -#define METER_IDENTIFIER "ELS" +#define METER_IDENTIFIER "LGZ" // ADJUSTME: Provide the OBIS Value from your smart-meter #define OBIS_VALUE_POWER "1.7.0" // ADJUSTME: Provide the OBIS Value from your smart-meter -#define OBIS_VALUE_TOTAL_ENERGY "1.8.0" +#define OBIS_VALUE_TOTAL_ENERGY "1.8.0" +#define OBIS_VALUE_TOTAL_ENERGY_TARIFF1 "1.8.1" +#define OBIS_VALUE_TOTAL_ENERGY_TARIFF2 "1.8.2" // The default baud rate at which the data is read #define INITIAL_BAUD_RATE 300 diff --git a/heltec-cubecell/heltec-cubecell.ino b/heltec-cubecell/heltec-cubecell.ino index 684ddeb..4777460 100644 --- a/heltec-cubecell/heltec-cubecell.ino +++ b/heltec-cubecell/heltec-cubecell.ino @@ -23,6 +23,8 @@ uint32_t sleepTime = 1200000; static MeterReader reader(Serial1); double power = 0; double totalkWh = 0; +double totalkWhTariff1 = 0; +double totalkWhTariff2 = 0; unsigned int uptimeCount = 0; uint8_t batteryPct = 0; uint16_t batteryVoltage = 0; @@ -34,7 +36,7 @@ float retrySleepTime = INITIAL_RETRY_SLEEP_TIME; // Every time there's an const float BACKOFF_MULTIPLIER = 1.5; // 5 7.5 11.25 16.8 23.3 37.9 56.9 85.42 128 /* LOGGER para */ -#define DEFAULT_LOG_LEVEL Info // DEBUG: set the Debug for more logging statements +#define DEFAULT_LOG_LEVEL Debug // DEBUG: set the Debug for more logging statements /*LoraWan channelsmask, default channels 0-7*/ uint16_t userChannelsMask[6] = { 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; @@ -178,6 +180,12 @@ void updateMeterData() { } else if (key.compare(OBIS_VALUE_TOTAL_ENERGY) == 0) { totalkWh = atof(value); } + else if (key.compare(OBIS_VALUE_TOTAL_ENERGY_TARIFF1) == 0) { + totalkWhTariff1 = atof(value); + } + else if (key.compare(OBIS_VALUE_TOTAL_ENERGY_TARIFF2) == 0) { + totalkWhTariff2 = atof(value); + } } } @@ -190,7 +198,7 @@ static void prepareTxFrame( uint8_t port ) for example, if use REGION_CN470, the max value for different DR can be found in MaxPayloadOfDatarateCN470 refer to DataratesCN470 and BandwidthsCN470 in "RegionCN470.h". */ - appDataSize = 10; + appDataSize = 18; // POWER (KW) uint16_t power_lora = power; @@ -204,14 +212,28 @@ static void prepareTxFrame( uint8_t port ) appData[4] = totalkWh_lora >> 8; appData[5] = totalkWh_lora & 0xFF; + // ENERGY (KWH) Tariff 1 + uint32_t totalkWh_loraTariff1 = totalkWhTariff1 * 100; + appData[6] = totalkWh_loraTariff1 >> 24; + appData[7] = totalkWh_loraTariff1 >> 16; + appData[8] = totalkWh_loraTariff1 >> 8; + appData[9] = totalkWh_loraTariff1 & 0xFF; + + // ENERGY (KWH) Tariff 1 + uint32_t totalkWh_loraTariff2 = totalkWhTariff2 * 100; + appData[10] = totalkWh_loraTariff2 >> 24; + appData[11] = totalkWh_loraTariff2 >> 16; + appData[12] = totalkWh_loraTariff2 >> 8; + appData[13] = totalkWh_loraTariff2 & 0xFF; + // BATTERY - appData[6] = batteryPct; + appData[14] = batteryPct; uint16_t batteryVoltage_lora = batteryVoltage; - appData[7] = batteryVoltage_lora >> 8; - appData[8] = batteryVoltage_lora & 0xFF;; + appData[15] = batteryVoltage_lora >> 8; + appData[16] = batteryVoltage_lora & 0xFF; // COUNTER - appData[9] = (uint8_t)uptimeCount; + appData[17] = (uint8_t)uptimeCount; } void onWakeUp() { From 810db3f1ba11b095eac1bb4a849803311587e827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Z=C3=BCrcher?= Date: Sat, 15 Oct 2022 11:32:08 +0200 Subject: [PATCH 2/5] Fix Tariff 1 and 2 handling, improve logs --- heltec-cubecell/heltec-cubecell.ino | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/heltec-cubecell/heltec-cubecell.ino b/heltec-cubecell/heltec-cubecell.ino index 4777460..c321e5d 100644 --- a/heltec-cubecell/heltec-cubecell.ino +++ b/heltec-cubecell/heltec-cubecell.ino @@ -36,7 +36,7 @@ float retrySleepTime = INITIAL_RETRY_SLEEP_TIME; // Every time there's an const float BACKOFF_MULTIPLIER = 1.5; // 5 7.5 11.25 16.8 23.3 37.9 56.9 85.42 128 /* LOGGER para */ -#define DEFAULT_LOG_LEVEL Debug // DEBUG: set the Debug for more logging statements +#define DEFAULT_LOG_LEVEL Info // DEBUG: set the Debug for more logging statements /*LoraWan channelsmask, default channels 0-7*/ uint16_t userChannelsMask[6] = { 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; @@ -179,11 +179,9 @@ void updateMeterData() { power = atof(value) * 1000; } else if (key.compare(OBIS_VALUE_TOTAL_ENERGY) == 0) { totalkWh = atof(value); - } - else if (key.compare(OBIS_VALUE_TOTAL_ENERGY_TARIFF1) == 0) { + } else if (key.compare(OBIS_VALUE_TOTAL_ENERGY_TARIFF1) == 0) { totalkWhTariff1 = atof(value); - } - else if (key.compare(OBIS_VALUE_TOTAL_ENERGY_TARIFF2) == 0) { + } else if (key.compare(OBIS_VALUE_TOTAL_ENERGY_TARIFF2) == 0) { totalkWhTariff2 = atof(value); } } @@ -273,6 +271,8 @@ void setup() { reader.start_monitoring(OBIS_VALUE_POWER); reader.start_monitoring(OBIS_VALUE_TOTAL_ENERGY); + reader.start_monitoring(OBIS_VALUE_TOTAL_ENERGY_TARIFF1); + reader.start_monitoring(OBIS_VALUE_TOTAL_ENERGY_TARIFF2); #if(AT_SUPPORT) enableAt(); @@ -312,6 +312,8 @@ void loop() { logger::debug("Uptime Count: %d", uptimeCount); logger::debug("Battery: %d [%]", batteryPct); logger::debug("Energy: %d [kWh]", (int)(totalkWh)); + logger::debug("Energy Tariff 1: %d [kWh]", (int)(totalkWhTariff1)); + logger::debug("Energy Tariff 2: %d [kWh]", (int)(totalkWhTariff2)); logger::debug("Power: %d [w]", (int)(power)); logger::debug("sleepTime: %d [s]", (int)(sleepTime / 1000.0)); logger::debug("retrySleepTime: %d [s]", (int)(retrySleepTime / 1000.0 )); From 7b8e97240d8cf926ca3eb728a50e4d57d6def19d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Z=C3=BCrcher?= Date: Sat, 15 Oct 2022 12:05:09 +0200 Subject: [PATCH 3/5] Added documentation --- readme.md | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index bb3c7f2..98aa20a 100644 --- a/readme.md +++ b/readme.md @@ -99,11 +99,154 @@ Connect as following: MAX_METER_READ_TIME 60 ``` +- [Landys&Gyr ZMD120AR21](https://wiki.volkszaehler.org/hardware/channels/meters/power/edl-ehz/landisgyr_zmd120ap?redirect=1) + ``` + SKIP_CHECKSUM_CHECK + METER_IDENTIFIER "LGZ" + BAUDRATE_CHANGE_DELAY: 500 + PARITY_SETTING SERIAL_7E1 + OBIS_VALUE_POWER "1.7.0 " + OBIS_VALUE_TOTAL_ENERGY "1.8.0" + OBIS_VALUE_TOTAL_ENERGY_TARIFF1 "1.8.1" + OBIS_VALUE_TOTAL_ENERGY_TARIFF2 "1.8.2" + INITIAL_BAUD_RATE 300 + SERIAL_IDENTIFICATION_READING_TIMEOUT 2000 + SERIAL_READING_TIMEOUT 500 + MAX_METER_READ_TIME 60 + ``` + + ## Acknowledgements - https://github.com/mwdmwd/iec62056-mqtt - https://wiki.volkszaehler.org/hardware/channels/meters/power/edl-ehz/elster_as1440 -# Home-Assitant Template Sensors + +# TheThingsNetwork Integration +For TTN we can define a uplink payload formater to convert the data to a be used later in Home-Assistant via MQTT + +```js +function decodeUplink(input) { + return { + data: { + bytes: input.bytes, + power: (input.bytes[0] << 8) + (input.bytes[1]), + energy: (input.bytes[2] << 24) + (input.bytes[3] << 16) + (input.bytes[4] << 8) + (input.bytes[5]), + energy1: (input.bytes[6] << 24) + (input.bytes[7] << 16) + (input.bytes[8] << 8) + input.bytes[9], + energy2: (input.bytes[10] << 24) + (input.bytes[11] << 16) + (input.bytes[12] << 8) + input.bytes[13], + batteryPCT: input.bytes[14], + battery:(input.bytes[15] << 8) + input.bytes[16], + counter: input.bytes[17] + }, + warnings: [], + errors: [] + }; +} +``` + +The coresponding MQQT Sensor in HomeAssistant can be configured like this. Replace APPLICAITON and DEVICE_EUI with the name of you TTN aplication and ID of your device. You can find the required data in the TTN console. + +```yaml +mqtt: + sensor: + - state_topic: "v3/APPLICATION@ttn/devices/DEVICE_EUI/up" + name: "Smart Meter Kwh" + unique_id: smart_meter_kwh + icon: mdi:chart-histogram + unit_of_measurement: "kWh" + state_class: total_increasing + device_class: energy + value_template: >- + {% set value = value_json.uplink_message.decoded_payload.energy | default(none) %} + {% if value == '00000000' %} + {{ none }} + {% else %} + {{ value | int(value,16)/100|float }} + {% endif %} + - state_topic: "v3/APPLICATION@ttn/devices/DEVICE_EUI/up" + name: "Smart Meter Kwh Peak" + unique_id: smart_meter_kwh_peak + icon: mdi:chart-histogram + unit_of_measurement: "kWh" + state_class: total_increasing + device_class: energy + value_template: >- + {% set value = value_json.uplink_message.decoded_payload.energy1 | default(none) %} + {% if value == '00000000' %} + {{ none }} + {% else %} + {{ value | int(value,16)/100|float }} + {% endif %} + - state_topic: "v3/APPLICATION@ttn/devices/DEVICE_EUI/up" + name: "Smart Meter Kwh OffPeak" + unique_id: smart_meter_kwh_offPeak + icon: mdi:chart-histogram + unit_of_measurement: "kWh" + state_class: total_increasing + device_class: energy + value_template: >- + {% set value = value_json.uplink_message.decoded_payload.energy2 | default(none) %} + {% if value == '00000000' %} + {{ none }} + {% else %} + {{ value | int(value,16)/100|float }} + {% endif %} + - state_topic: "v3/APPLICATION@ttn/devices/DEVICE_EUI/up" + name: "Smart Meter Power" + unique_id: smart_meter_power + icon: mdi:flash-outline + unit_of_measurement: "W" + state_class: measurement + device_class: power + value_template: >- + {% set value = value_json.uplink_message.decoded_payload.power | default(none) %} + {% if value == '0000' %} + {{ none }} + {% else %} + {{ value | int(value,16) }} + {% endif %} + - state_topic: "v3/APPLICATION@ttn/devices/DEVICE_EUI/up" + name: "Smart Meter Battery" + unique_id: smart_meter_battery + icon: mdi:battery + unit_of_measurement: "%" + device_class: battery + value_template: >- + {% set value = value_json.uplink_message.decoded_payload.battery | default(none) %} + {% if value == '00' %} + {{ none }} + {% else %} + {{ value | int(value,16) }} + {% endif %} + - state_topic: "v3/APPLICATION@ttn/devices/DEVICE_EUI/up" + name: "Smart Meter Battery Voltage" + unique_id: smart_meter_battery + icon: mdi:battery + unit_of_measurement: "mV" + state_class: measurement + device_class: battery + value_template: >- + {% set value = value_json.uplink_message.decoded_payload.batteryPCT | default(none) %} + {% if value == '0000' %} + {{ none }} + {% else %} + {{ value | int(value,16) }} + {% endif %} + - state_topic: "v3/APPLICATION@ttn/devices/DEVICE_EUI/up" + name: "Smart Meter Up-Counter" + unique_id: smart_meter_upcounter + icon: mdi:counter + unit_of_measurement: "times" + value_template: >- + {% set value = value_json.uplink_message.decoded_payload.counter | default(none) %} + {% if value == '00' %} + {{ none }} + {% else %} + {{ value | int(value,16) }} + {% endif %} +``` + + +# Home-Assistant Template Sensors ```yaml From eef5b71b5622d15bd5be9c139123f7b154111796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Z=C3=BCrcher?= Date: Sat, 15 Oct 2022 12:07:14 +0200 Subject: [PATCH 4/5] Fixed documentation --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 98aa20a..fce797f 100644 --- a/readme.md +++ b/readme.md @@ -219,7 +219,7 @@ mqtt: {% endif %} - state_topic: "v3/APPLICATION@ttn/devices/DEVICE_EUI/up" name: "Smart Meter Battery Voltage" - unique_id: smart_meter_battery + unique_id: smart_meter_battery_voltage icon: mdi:battery unit_of_measurement: "mV" state_class: measurement From fd26a352298b5532c33052d9573cdd3a6899c502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Z=C3=BCrcher?= Date: Sat, 15 Oct 2022 12:36:51 +0200 Subject: [PATCH 5/5] Fix typo --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index fce797f..71da8a8 100644 --- a/readme.md +++ b/readme.md @@ -211,7 +211,7 @@ mqtt: unit_of_measurement: "%" device_class: battery value_template: >- - {% set value = value_json.uplink_message.decoded_payload.battery | default(none) %} + {% set value = value_json.uplink_message.decoded_payload.batteryPCT | default(none) %} {% if value == '00' %} {{ none }} {% else %} @@ -225,7 +225,7 @@ mqtt: state_class: measurement device_class: battery value_template: >- - {% set value = value_json.uplink_message.decoded_payload.batteryPCT | default(none) %} + {% set value = value_json.uplink_message.decoded_payload.battery | default(none) %} {% if value == '0000' %} {{ none }} {% else %}