Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Landis&Gyr Support #1

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions heltec-cubecell/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 29 additions & 5 deletions heltec-cubecell/heltec-cubecell.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -177,6 +179,10 @@ 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) {
totalkWhTariff1 = atof(value);
} else if (key.compare(OBIS_VALUE_TOTAL_ENERGY_TARIFF2) == 0) {
totalkWhTariff2 = atof(value);
}
}
}
Expand All @@ -190,7 +196,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;
Expand All @@ -204,14 +210,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() {
Expand Down Expand Up @@ -251,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();
Expand Down Expand Up @@ -290,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 ));
Expand Down
145 changes: 144 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.batteryPCT | 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_voltage
icon: mdi:battery
unit_of_measurement: "mV"
state_class: measurement
device_class: battery
value_template: >-
{% set value = value_json.uplink_message.decoded_payload.battery | 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

Expand Down