substitutions:
  device_name: utilities-meter
  friendly_name: um
esphome:
  name: ${device_name}
  project:
    name: d1.utilities-meter
    version: "1.0.0"
  name_add_mac_suffix: true

esp8266:
  board: esp01_1m
  restore_from_flash: true


# Based on:
# - Slimme Lezer for the Electricity Meter
#   - https://github.com/zuidwijk/dsmr/blob/main/slimmelezer.yaml
#   - @ 0f34e14 on Oct 10
# - Blog post for the Water Meter
#   - https://www.pieterbrinkman.com/2022/02/02/build-a-cheap-water-usage-sensor-using-esphome-home-assistant-and-a-proximity-sensor/
#   - Using the same pin for multiple sensor types is no longer supported:
#     - https://github.com/esphome/issues/issues/3364#issuecomment-1179691203
#   - Connect same input to 2 GPIOs to make them read the same sensor, but keep separate counts internally.


wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.1.150
    gateway: 192.168.1.254
    subnet: 255.255.255.0    
    dns1: 192.168.1.1

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${device_name}
    password: ${device_name}

captive_portal:

web_server:
  port: 80
ota:
  - platform: !secret ota_platform
    password: !secret ota_password

# Enable logging
#
# Baud-rate is set to zero to disable serial logging so that the UART interface can perform well enough to receive the
# DSMR packages.
#   - https://esphome.io/components/sensor/dsmr.html#improving-reader-results
logger:
   baud_rate: 0

# Enable Home Assistant API
api:
  reboot_timeout: 30min
  services:
    - service: set_pulse_total
      variables:
        new_pulse_total: int
      then:
        - pulse_counter.set_total_pulses:
            id: water_sensor_freq
            value: !lambda 'return new_pulse_total;'

uart:
    id: uart_bus
    rx_pin:
      number: 3
      inverted: true
    rx_buffer_size: 1700
    baud_rate: 115200

dsmr:
  id: dsmr_instance
  max_telegram_length: 1700

sensor:
  - platform: dsmr
    energy_delivered_tariff1:
      name: ${friendly_name}"Energy Consumed Tariff 1"
    energy_delivered_tariff2:
      name: ${friendly_name}"Energy Consumed Tariff 2"
    power_delivered:
      name: ${friendly_name}"Power Consumed"
      accuracy_decimals: 3
    electricity_failures:
      name: ${friendly_name}"Electricity Failures"
      icon: mdi:alert
    electricity_long_failures:
      name: ${friendly_name}"Long Electricity Failures"
      icon: mdi:alert
    current_l1:
      name: ${friendly_name}"Current Phase 1"
      accuracy_decimals: 2
    current_l2:
      name: ${friendly_name}"Current Phase 2"
      accuracy_decimals: 2
    current_l3:
      name: ${friendly_name}"Current Phase 3"
      accuracy_decimals: 2
    power_delivered_l1:
      name: ${friendly_name}"Power Consumed Phase 1"
      accuracy_decimals: 3
    power_delivered_l2:
      name: ${friendly_name}"Power Consumed Phase 2"
      accuracy_decimals: 3
    power_delivered_l3:
      name: ${friendly_name}"Power Consumed Phase 3"
      accuracy_decimals: 3

    power_returned:
      name: "Power Produced"
      unit_of_measurement: "W"
      state_class: "measurement"
      accuracy_decimals: 0
      filters:
        - multiply: 1000

    energy_returned_tariff1:
      name: "Energy Produced Tariff 1"
      state_class: total_increasing
    energy_returned_tariff2:
      name: "Energy Produced Tariff 2"
      state_class: total_increasing

    power_returned_l1:
      name: "Power Produced Phase 1"
      unit_of_measurement: "W"
      state_class: "measurement"
      accuracy_decimals: 0
      filters:
        - multiply: 1000
    power_returned_l2:
      name: "Power Produced Phase 2"
      unit_of_measurement: "W"
      state_class: "measurement"
      accuracy_decimals: 0
      filters:
        - multiply: 1000
    power_returned_l3:
      name: "Power Produced Phase 3"
      unit_of_measurement: "W"
      state_class: "measurement"
      accuracy_decimals: 0
      filters:
        - multiply: 1000
        
                      

    gas_delivered:
      name: ${friendly_name}"Gas Consumed"
  - platform: template
    # extra sensor to calculate the missing gas value
    name: Gas Consumed Calculated
    id: gas_consumed_calculated
    device_class: gas
    state_class: total_increasing
    accuracy_decimals: 3
    unit_of_measurement: "m³"


  - platform: uptime
    name: "Uptime"
    update_interval: 60s

  - platform: wifi_signal
    name: "WiFi Signal Strenght"
    id: wifi_signal_db
    update_interval: 60s

  # Reports the WiFi signal strength in %.
  # https://esphome.io/components/sensor/wifi_signal.html
  - platform: copy
    source_id: wifi_signal_db
    name: "WiFi Signal (percent)"
    id: wifi_signal_pct
    unit_of_measurement: "Signal %"
    accuracy_decimals: 0
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    entity_category: "diagnostic"

  - platform: pulse_counter
    pin: GPIO14
    name: "Sensor Average Frequency"
    id: water_sensor_freq
    accuracy_decimals: 1
    update_interval : 15s
    total:
      name: "Sensor Pulses"
      id: water_sensor_pulses
      unit_of_measurement: "pulses"
      accuracy_decimals: 0
      state_class: total_increasing

  # Timeout after 1 minute, for a minimum resolution of 1.0 litres per minute.
  # Default is 5 minutes, meaning 1 pulse per 5 minutes, which is 0.2 litres per minute.
  - platform: pulse_meter
    pin: 2
    name: ${friendly_name}"Water Instantaneous Consumption"
    id: water_inst_cons
    unit_of_measurement: "litre/min"
    accuracy_decimals: 1
    timeout: 1min
    icon: "mdi:water-pump"
    total:
      name: ${friendly_name}"Water Consumed"
      id: water_consumed
      unit_of_measurement: "litre"
      accuracy_decimals: 2
      device_class: water
      state_class: total_increasing
      icon: "mdi:water"

  - platform: copy
    source_id: water_consumed
    name: ${friendly_name}"Water Meter Reading"
    id: water_meter_reading
    unit_of_measurement: "m³"
    accuracy_decimals: 2
    device_class: water
    state_class: total_increasing
    icon: "mdi:water"
    filters:
      - multiply: 0.001

  - platform: copy
    source_id: water_consumed
    name: ${friendly_name}"Water Meter Total"
    id: water_meter_total
    unit_of_measurement: "m³"
    accuracy_decimals: 3
    device_class: water
    state_class: total_increasing
    icon: "mdi:water"
    filters:
      - multiply: 0.001

text_sensor:
  - platform: dsmr
    identification:
      name: ${friendly_name}"DSMR Identification"
    p1_version:
      name: ${friendly_name}"DSMR Version"
   
    gas_delivered_text:
      name: ${friendly_name}"Gas Consumed Text"
      id: gas_consumed_text
      # if the state of "gas_delivered_text" changes a new value for the extra gas sensor is calculated
      on_value:
        then:
          - lambda: |-
              std::string str = id(gas_consumed_text).state;
              std::vector<std::string> v;
              char * token;
              char seps[] = "()";
              token = strtok (&str[0],seps);
              while (token != NULL)
              {
                v.push_back(token);
                token = strtok (NULL, seps);
              }
              int count = 0;
              for ( std::string s : v )
              {
                 if (count == 6) {
                   id(gas_consumed_calculated).publish_state(parse_number<float>(s.c_str()).value());
                 }   
                 count++;
              } 


  - platform: wifi_info
    ip_address:
      name: "IP Address"
    ssid:
      name: "WiFi SSID"
    bssid:
      name: "WiFi BSSID"

  - platform: version
    name: "ESPHome Version"
    hide_timestamp: false
