diff --git a/esphome/example.yml b/esphome/example.yml new file mode 100644 index 0000000..e92700c --- /dev/null +++ b/esphome/example.yml @@ -0,0 +1,293 @@ +# This configuration is loosely based on https://github.com/zuidwijk/slimmelezer-wt32-eth01 +substitutions: + device_name: p1reader + device_description: "P1 reader" + +esphome: + name: ${device_name} + comment: "${device_description}" + name_add_mac_suffix: false + on_boot: + then: + - if: + condition: + lambda: return id(has_key); + then: + - lambda: |- + std::string key(id(stored_decryption_key), 32); + id(dsmr_instance).set_decryption_key(key); + else: + - logger.log: + level: info + format: "Not using decryption key. If you need to set a key use Home Assistant service 'ESPHome: ${device_name}_set_dsmr_key'" + +esp32: + board: esp32dev + framework: + type: arduino + +# Enable logging +logger: + baud_rate: 115200 + logs: + component: ERROR +# Enable Home Assistant API +# api: +# services: +# service: set_dsmr_key +# variables: +# private_key: string +# then: +# - logger.log: +# format: Setting private key %s. Set to empty string to disable +# args: [private_key.c_str()] +# - globals.set: +# id: has_key +# value: !lambda "return private_key.length() == 32;" +# - lambda: |- +# if (private_key.length() == 32) +# private_key.copy(id(stored_decryption_key), 32); +# id(dsmr_instance).set_decryption_key(private_key); + +ota: + safe_mode: true +# dashboard_import: +# package_import_url: github://zuidwijk/slimmelezer-wt32-eth01/sl32.yaml@main + +uart: + id: uart_dsmr + baud_rate: 115200 + rx_pin: GPIO5 + rx_buffer_size: 1700 + +web_server: + port: 80 + +network: + enable_ipv6: true + +ethernet: + type: LAN8720 + mdc_pin: GPIO23 + mdio_pin: GPIO18 + clk_mode: GPIO0_IN + phy_addr: 1 + power_pin: GPIO16 + +globals: + - id: has_key + type: bool + restore_value: yes + initial_value: "false" + - id: stored_decryption_key + type: char[32] + restore_value: yes + +dsmr: + uart_id: uart_dsmr + id: dsmr_instance + max_telegram_length: 1700 + # For Luxembourg users set here your decryption key + #decryption_key: !secret decryption_key // enable this when using decryption for Luxembourg; key like '00112233445566778899AABBCCDDEEFF' + + +# Time is required for Wireguard to function properly. +time: + - platform: sntp + id: sntp_time + timezone: Europe/Amsterdam + servers: + - 0.pool.ntp.org + - 1.pool.ntp.org + - 2.pool.ntp.org + +# wireguard: +# address: YOUR_ADDRESS +# private_key: YOUR_PRIVATE_KEY +# peer_endpoint: YOUR_PEER_ENDPOINT +# peer_public_key: YOUR_PEER_PUBLIC_KEY + +# # Optional netmask (below are the defaults if omitted) +# # https://esphome.io/components/wireguard.html#static-routes-and-outgoing-connections +# netmask: 255.255.0.0 + +# # Optional endpoint port (WireGuard default if omitted) +# peer_port: 51820 + +# # Optional pre-shared key (omit if not in use) +# # peer_preshared_key: XxYyZzWw...= + +# # Optional list of ip/mask (any host is allowed if omitted) +# peer_allowed_ips: +# - 10.10.10.0/24 + +# # Optional keepalive (disabled by default) +# peer_persistent_keepalive: 25s + +mqtt: +# https://esphome.io/components/mqtt.html +# topic_prefix (Optional, string): The prefix used for all MQTT messages. Should not contain trailing slash. Defaults to . Use null to disable publishing or subscribing of any MQTT topic unless it is explicitly configured. + topic_prefix: null + discovery: false + discovery_retain: false + birth_message: + topic: p1/status + payload: online + will_message: + topic: p1/status + payload: offline + + id: p1_reader + broker: 10.10.10.23 + port: 1883 + username: p1_reader + password: your_password + +sensor: + - platform: dsmr + gas_delivered: + name: "Gas Consumed" + id: gas_delivered + energy_delivered_tariff1: + name: "Energy Consumed Tariff 1" + id: energy_delivered_tariff1 + energy_delivered_tariff2: + name: "Energy Consumed Tariff 2" + id: energy_delivered_tariff2 + energy_returned_tariff1: + name: "Energy Produced Tariff 1" + id: energy_returned_tariff1 + energy_returned_tariff2: + name: "Energy Produced Tariff 2" + id: energy_returned_tariff2 + power_delivered: + name: "Power Consumed" + accuracy_decimals: 3 + id: power_delivered + power_returned: + name: "Power Produced" + accuracy_decimals: 3 + id: power_returned + electricity_failures: + name: "Electricity Failures" + icon: mdi:alert + id: electricity_failures + electricity_long_failures: + name: "Long Electricity Failures" + icon: mdi:alert + id: electricity_long_failures + voltage_l1: + name: "Voltage Phase 1" + id: voltage_l1 + accuracy_decimals: 0 + voltage_l2: + name: "Voltage Phase 2" + id: voltage_l2 + accuracy_decimals: 0 + voltage_l3: + name: "Voltage Phase 3" + id: voltage_l3 + accuracy_decimals: 0 + current_l1: + name: "Current Phase 1" + id: current_l1 + current_l2: + name: "Current Phase 2" + id: current_l2 + current_l3: + name: "Current Phase 3" + id: current_l3 + power_delivered_l1: + name: "Power Consumed Phase 1" + accuracy_decimals: 3 + id: power_delivered_l1 + power_delivered_l2: + name: "Power Consumed Phase 2" + accuracy_decimals: 3 + id: power_delivered_l2 + power_delivered_l3: + name: "Power Consumed Phase 3" + accuracy_decimals: 3 + id: power_delivered_l3 + power_returned_l1: + name: "Power Produced Phase 1" + accuracy_decimals: 3 + id: power_returned_l1 + power_returned_l2: + name: "Power Produced Phase 2" + accuracy_decimals: 3 + id: power_returned_l2 + power_returned_l3: + name: "Power Produced Phase 3" + accuracy_decimals: 3 + id: power_returned_l3 + on_value: + - mqtt.publish_json: + topic: p1/metrics + payload: |- + root["t"] = id(dsmr_timestamp).state; + root["dt1"] = id(energy_delivered_tariff1).state * 1000; + root["dt2"] = id(energy_delivered_tariff2).state * 1000; + root["rt1"] = id(energy_returned_tariff1).state * 1000; + root["rt2"] = id(energy_returned_tariff2).state * 1000; + root["d"] = id(power_delivered).state * 1000; + root["r"] = id(power_returned).state * 1000; + root["f"] = id(electricity_failures).state; + root["fl"] = id(electricity_long_failures).state; + root["g"] = id(gas_delivered).state * 1000; + root["v1"] = id(voltage_l1).state; + root["v2"] = id(voltage_l2).state; + root["v3"] = id(voltage_l3).state; + root["c1"] = id(current_l1).state; + root["c2"] = id(current_l2).state; + root["c3"] = id(current_l3).state; + root["d1"] = id(power_delivered_l1).state * 1000; + root["d2"] = id(power_delivered_l2).state * 1000; + root["d3"] = id(power_delivered_l3).state * 1000; + root["r1"] = id(power_returned_l1).state * 1000; + root["r2"] = id(power_returned_l2).state * 1000; + root["r3"] = id(power_returned_l3).state * 1000; + + - platform: uptime + name: "SlimmeLezer Uptime" + - platform: wireguard + latest_handshake: + name: 'WireGuard Latest Handshake' + +text_sensor: + - platform: dsmr + identification: + name: "DSMR Identification" + p1_version: + name: "DSMR Version" + timestamp: + name: "DSMR Timestamp" + id: dsmr_timestamp +# (YYMMDDhhmmssX, where X is S or W for summer- or wintertime). +# https://github.com/matthijskooijman/arduino-dsmr/blob/master/README.md +# https://srolija.medium.com/gos-summer-time-localization-issues-4c8ab702806b +# https://github.com/thomasvnl/P1DSMRReader-ESPHome +# https://pkg.go.dev/github.com/mijnverbruik/dsmr#Timestamp.Position +# https://pkg.go.dev/github.com/mijnverbruik/dsmr#Timestamp + - platform: version + name: "ESPHome Version" + hide_timestamp: true + - platform: ethernet_info + ip_address: + name: ESP IP Address + - platform: wireguard + address: + name: 'WireGuard Address' + - platform: template + name: "Current time" + lambda: |- + char str[17]; + time_t currTime = id(sntp_time).now().timestamp; + strftime(str, sizeof(str), "%Y-%m-%d %H:%M", localtime(&currTime)); + return { str }; + update_interval: 1s + +binary_sensor: + - platform: wireguard + status: + name: 'WireGuard Status'