zibous / ha-watermeter

Data provider for smartmeter watermeter.
GNU General Public License v3.0
183 stars 27 forks source link

No water measurement only battery life and alarms? #53

Closed WulleWulleWapWap closed 2 weeks ago

WulleWulleWapWap commented 2 weeks ago

Hello Guys, maybe someone can help me with my problems.

I have running wm-esp32.yaml and got my Diehl IZAR RC 868 I R4 PL running and also working in my HA. Unfortunately, I only get information like battery life and alarm etc. Water values ​​are not displayed in the HA or in the log. Did I make a mistake in the config or does anyone have a tip for me? When I translate the telegram I have water values...

Debug log:

[09:05:53][D][mbus:034]: Processing T1 A frame
[09:05:53][V][mbus:045]: Frame: 36571C99934D4EC5932D6B1358E39C2ECC9398D2CD34B59634B64D4CEA6CB1A3594F2A4D5A6C8DB0DA715B471C (45) [RAW]
[09:05:53][V][mbus:052]: Frame: 1944A51178073087022438E7A1311300135172F886157EF10AE181FD0C44 (30) [with CRC]
[09:05:53][V][mbus:095]: Validating CRC for Block1
[09:05:53][V][crc:031]:     calculated: 0x38E7, read: 0x38E7
[09:05:53][V][mbus:115]: Validating CRC for Block2
[09:05:53][V][crc:031]:     calculated: 0x0C44, read: 0x0C44
[09:05:53][V][mbus:062]: Frame: 1944A511780730870224A1311300135172F886157EF10AE181FD (26) [without CRC]
[09:05:53][D][wmbus:097]: Using driver 'izar' for ID [0x87300778] RSSI: -22 dBm LQI: 128 Frame: T1 A T: 1944A511780730870224A1311300135172F886157EF10AE181FD (26)
[09:05:53][V][wmbus:121]: Publishing 'current_alarms' = 0.0000
[09:05:53][D][wmbus:827]: Alarm message: \xdc$\xfb?, error code: 0
[09:05:53][V][wmbus:121]: Publishing 'previous_alarms' = 0.0000
[09:05:53][D][wmbus:857]: Alarm message: \xdc$\xfb?, error code: 0
[09:05:53][V][wmbus:121]: Publishing 'remaining_battery_life_y' = 9.5000
[09:05:53][V][wmbus:121]: Publishing 'transmit_period_s' = 8.0000

wmbusmeter online:

telegram=|1944A511780730870224A1_311300135172F886157EF10AE181FD|

Auto driver    : izar
Similar driver : unknown 00/00
Using driver   : izar 00/00
000   : 19 length (25 bytes)
001   : 44 dll-c (from meter SND_NR)
002   : a511 dll-mfct (DME)
004   : 30870224 dll-id (24028730)
008   : 78 dll-version
009   : 07 dll-type (Water meter)
010   : a1 tpl-ci-field (Mfct specific)
011 C?: 311300135172F886157EF10AE181FD mfct specific

{
    "media":"water",
    "meter":"izar",
    "name":"",
    "id":"24028730",
    "last_month_total_m3":0,
    "remaining_battery_life_y":9.5,
    "total_m3":15.517,
    "transmit_period_s":8,
    "current_alarms":"no_alarm",
    "last_month_measure_date":"2024-12-01",
    "previous_alarms":"no_alarm",
    "timestamp":"2024-10-29T09:06:53Z"
}

Using: wmbusmeters: 1.17.1-18-g26760f3
26760f3838aaffe0830a73316fc6b0a36ec2300b

Here is my wm-esp32.yaml:

---
## ---------------------------------------------------------------------------
## WMBUS METER az-delivery-devkit-v4 + CC1101 for Diehl IZAR RC 868 I R4 PL
## Hardware: ESP32 240MHz, 520KB RAM, 4MB Flash
##
## This version shows data from the defined watermeter and
## uses the watermeterID (HEX) from the secrets.yaml file.
##
## usage:  1. Using the last wM-Bus component
##         2. Using Homassistant API (discovery + devices)
##         3. Using HTTP Post to service server (optional)
##         4. Using wmbusmeters i a pipe (optional)
##         5. uses backup component (optinal)
##         6. uses syslog component (optinal)
##
## Backup:  http://water-meter-esp.local/config.yaml
##          curl -v 'http://water-meter-esp/config.yaml' --digest -u USERNAME:PASSWORD -o config.yaml
## REST:    curl -i http://water-meter-esp.local/text_sensor/watermeterdata
## SYSLOG:  tail -f /var/log/syslog | grep "water-meter"
##
## ---------------------------------------------------------------------------
substitutions:

  ## device settings
  device_name_short: "water-meter-esp"
  device_description: "Wasserzähler ESP32, CUL - CC1101, IZAR module (Diehl IZAR RC 868 I R4 PL (SzczepanLeon) my Watermeter"
  projectname: "Diehl IZAR RC 868.Watermeter"
  friendly_name: "Watermeter" # device name
  appversion: "2.0.9"

  ## logger settings
  log_level: "VERBOSE"    # not that logging need memory, so in production mode use "WARN"
  log_wmbus: "VERBOSE"      # Loglevel for wmbus meters component
  log_baudrate: "115200"  # use 0 to disable serial UART port logging.

  ## data service (optional, default: False)
  ## use only if you have a service host present
  service_enabled: "false"
  service_url: !secret service_host
  service: "izar.watermeter"

## -----------------------------------------------------------------
## HARDWARE az-delivery-devkit-v4,ESP32 240MHz, 520KB RAM, 4MB Flash
## -----------------------------------------------------------------
esp32:
  board: az-delivery-devkit-v4
  framework:
    type: arduino

# Customize the frequency in which data is flushed to the flash.
preferences:
  flash_write_interval: 10min

## ----------------------------------------------------------------
## APPLICATION ESPHOME
## ----------------------------------------------------------------
esphome:
  name: ${device_name_short}
  comment: ${device_description}
  # Automatically add the mac address to the name
  # so you can use a single firmware for all devices
  name_add_mac_suffix: false
  # additiona compile otions
  platformio_options:
    platform: espressif32
    board: az-delivery-devkit-v4
    ## larger stack size required with all registers enable_load_test
    build_flags:
      - "-DCONFIG_ARDUINO_LOOP_STACK_SIZE=32768"
    # monitor_filters: esp32_exception_decoder
  project:
    name: ${projectname}
    version: ${appversion}
  build_path: ./build/${device_name_short}
  on_boot:
    then:
      - globals.set:
          id: boot_counter
          value: !lambda "return id(boot_counter)+=1;"
      - globals.set:
          id: send_millisecond
          value: !lambda "return millis();"
      - logger.log:
          level: WARN
          tag: "system"
          format: "BOOTMESSAGE:${device_name_short} API is connected, Device ready!"
      - component.update: bootcounter
  on_shutdown:
    then:
      - logger.log:
          level: ERROR
          tag: "system"
          format: "BOOTMESSAGE:${device_name_short} is down!"

## ----------------------------------------------------------------
## EXTERNAL COMPONENTS
## ----------------------------------------------------------------
external_components:

  # uses the latest version from SzczepanLeon (github)
  # https://github.com/SzczepanLeon/esphome-components
  # You can make ESPHome check the repository every time by setting this option to 0s
  - source: github://SzczepanLeon/esphome-components@3.2.3
    refresh: 0s
    components: [wmbus]

  # optinal: use local component from
  # https://github.com/zdzichu6969/esphome-components
  - source:
      type: local
      path: custom_components
    components: [backup]

  # optinal: use local component from
  # https://github.com/TheStaticTurtle/esphome_syslog
  - source:
      type: local
      path: custom_components
    components: [syslog]

# ----------------------------------------------------------------
# Save your ESPHome device configuration in firmware and and
# recover it if you lost source files.
# ----------------------------------------------------------------
backup:
  auth:
    username: !secret web_username
    password: !secret web_password
  force_update: false

## ---------------------------------------------------
## COMPONENT SYSLOG SERVICE ENABLED
## ---------------------------------------------------
syslog:
  ip_address: !secret syslog_server
  port: !secret syslog_port
  min_level: DEBUG
  enable_logger: true

## ---------------------------------------------------
## COMPONENT LOGGER
## ---------------------------------------------------
logger:
  id: appslogger
  level: ${log_level}
  baud_rate: ${log_baudrate}
  logs:
    wmbus: ${log_wmbus}
    wMBus-lib: ${log_wmbus}
    sensor: WARN
    sensor.filter: WARN
    text_sensor: WARN
    api.service: ERROR
    json: ERROR
    mqtt: WARN
    scheduler: ERROR
    internal_temperature: ERROR
    wifi: WARN
    component: ERROR
    api: WARN

## ----------------------------------------------------------------
## GLOBALS VARIABLES
## ----------------------------------------------------------------
globals:

  - id: boot_counter
    type: int
    restore_value: yes
    initial_value: "0"

  - id: last_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: current_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: hour_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: daily_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: yesterday_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: week_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: lastmonth_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: year_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: send_millisecond
    type: int
    restore_value: no
    initial_value: '0'

  - id: cc1101_state
    type: int
    restore_value: no
    initial_value: '0'

  - id: alarm_error_text
    type: std::vector<std::string>
    restore_value: no
    # initial_value: '{"no error", "general_alarm","leakage","meter_blocked","back_flow","underflow","overflow","submarine","sensor_fraud","mechanical_fraud"}'
    initial_value: '{"Keiner", "Fehler","Zähler undicht","Zähler blockiert","Wasser Rückfluss","Wasser Unterlauf","Wasser Überlauf","Überschwemung","Sensor Fehler", "Mechanischer Fehler"}'

  - id: cc1101_state_message
    type: std::vector<std::string>
    restore_value: no
    initial_value: '{"Init", "Warte auf Daten", "Daten empfangem", "Ready", "Error"}'

## ---------------------------------------------------
## WIFI Settings
## ---------------------------------------------------
wifi:
  networks:
   # unifi accesspoint 2.4Ghz
    - ssid: !secret ssid1_name
      password: !secret ssid1_pswd
      priority: 1
    # office apple capsulate accesspoint 2.4Ghz
    - ssid: !secret ssid3_name
      password: !secret ssid3_pswd
      priority: 2
    # living room apple capsulate accesspoint 2.4Ghz
    - ssid: !secret ssid2_name
      password: !secret ssid2_pswd
      priority: 3
  domain: !secret domain
  ap:
    # ssid (Optional, string): The name of the access point to create. Leave empty to use the device name.
    password: !secret app_pswd

## ---------------------------------------------------
## mDNS Component
## ---------------------------------------------------
mdns:
  # if mDNS is disabled, they will no longer be able to automatically find your devices.
  # It is recommended to leave mDNS enabled.
  disabled: false

## ---------------------------------------------------
## COMPONENT CAPTIVE PORTAL
## ---------------------------------------------------
captive_portal:

## ---------------------------------------------------
## COMPONENT OTA
## ---------------------------------------------------
ota:
  password: !secret ota_pswd
  platform: esphome
  on_begin:
    then:
      - logger.log:
          format: "OTA Start"
          tag: "OTA"
          level: WARN
  on_progress:
    then:
      - logger.log:
          level: WARN
          tag: "OTA"
          format: "OTA progress %0.1f%%"
          args: ["x"]
  on_end:
    then:
      - logger.log:
          format: "OTA End"
          tag: "OTA"
          level: WARN
  on_error:
    then:
      - logger.log:
          format: "OTA update error %d"
          tag: "OTA"
          level: ERROR
          args: ["x"]
safe_mode:

## ---------------------------------------------------
## COMPONENT WEBSERVER (local hosted)
## ---------------------------------------------------
web_server:
  port: 80
  version: 3
  js_url: !secret webserver_jsurl

## ---------------------------------------------------
## COMPONENT Home Assistant API
## Homeassistant service call (all values in liter):
## ---------------------------------------------------
## service: esphome.water_meter_esp_set_watermeter_esp_data
## data:
##   water_val_hour: 0.00
##   water_val_day: 167.00
##   water_val_yesterday: 240.35
##   water_val_week: 901.00
##   water_val_year: 33143.00
##   water_val_lastmonth: 7580.25
## ---------------------------------------------------
api:
  id: espapi_wmbus_esp32
  port: 6053
  reboot_timeout: 0s
  # https://esphome.io/components/api.html?highlight=api
  encryption:
    key: "inH49O9jBeK5yTGb1X2g4WV/1aS6YKUpu3Vu277fDgw="
  services:
    - service: set_watermeter_esp_data
      variables:
        water_val_hour: float
        water_val_day: float
        water_val_yesterday: float
        water_val_week: float
        water_val_year: float
        water_val_lastmonth: float
      then:
        - globals.set:
            id: hour_value
            value: !lambda |-
              if((water_val_hour) and (water_val_hour)>0.001){
                ESP_LOGD("system", "Set hourly value to: %f", water_val_hour);
                return (water_val_hour);
              }else{
                ESP_LOGD("system", "Skip setting hourly value");
                return id(hour_value);
              };
              id(waterhour).publish_state(id(hour_value));

        - globals.set:
            id: daily_value
            value: !lambda |-
              if((water_val_day) and (water_val_day)>0.001){
                ESP_LOGD("system", "Set daily value to: %f", water_val_day);
                return (water_val_day);
              }else{
                ESP_LOGD("system", "Skip setting hourly value");
                return id(hour_value);
              };
              id(waterday).publish_state(id(daily_value));

        - globals.set:
            id: yesterday_value
            value: !lambda |-
              if((water_val_yesterday) and (water_val_yesterday)>0.001){
                ESP_LOGD("system", "Set yesterday value to: %f", water_val_yesterday);
                return (water_val_yesterday);
              }else{
                ESP_LOGD("system", "Skip setting yesterday value");
                return id(yesterday_value);
              };
              id(wateryesterday).publish_state(id(hour_value));

        - globals.set:
            id: week_value
            value: !lambda |-
              if((water_val_week) and (water_val_week)>0.001){
                ESP_LOGD("system", "Set weekly value to: %f", water_val_week);
                return (water_val_week);
              }else{
                ESP_LOGD("system", "Skip setting weekly value");
                return id(week_value);
              };
              id(waterweek).publish_state(id(week_value));

        - globals.set:
            id: lastmonth_value
            value: !lambda |-
              if((water_val_lastmonth) and (water_val_lastmonth)>0.001){
                ESP_LOGD("system", "Set last month value to: %f", water_val_lastmonth);
                return (water_val_lastmonth);
              }else{
                ESP_LOGD("system", "Skip setting last month value");
                return id(lastmonth_value);
              };
              id(waterlastmonth).publish_state(id(lastmonth_value));

        - globals.set:
            id: year_value
            value: !lambda |-
              if((water_val_year) and (water_val_year)>0.001){
                ESP_LOGD("system", "Set last yearly value to: %f", water_val_year);
                return (water_val_year);
              }else{
                ESP_LOGD("system", "Skip setting last yearly value");
                return id(year_value);
              };
              id(wateryear).publish_state(id(year_value));

        - logger.log:
            tag: "system"
            format: "All new Values set: hour: %.3f, day: %.3f, week: %.3f, last month: %.3f, year: %.3f"
            level: INFO
            args:
              [
                "id(hour_value)",
                "id(daily_value)",
                "id(week_value)",
                "id(lastmonth_value)",
                "id(year_value)",
              ]

## ---------------------------------------------------
## SNTP COMPONENT
## ---------------------------------------------------
time:
  - platform: sntp
    id: time_sntp
    timezone: Europe/Berlin
    servers:
      - !secret local_sntp
      - 0.at.pool.ntp.org
      - 0.pool.ntp.org
    on_time_sync:
      # Components should trigger on_time_sync when they update the system clock.
      then:
        - if:
            condition:
              lambda: 'return id(device_lastBoot_time).state == "";'
            then:
              - text_sensor.template.publish:
                  id: device_lastBoot_time
                  state: !lambda return id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z");
        - logger.log:
            level: WARN
            tag: "system"
            format: "Synchronized sntp clock"
        - script.execute: set_status_message

    on_time:

      # check cc1101 telegram state message every 30s
      - seconds: 30
        then:
          - script.execute: set_status_message

      # reset hourly value
      - seconds: 0
        minutes: 0
        then:
          - globals.set:
              id: hour_value
              value: "0.00"
          - lambda: id(waterhour).publish_state(id(hour_value));
          - logger.log:
              tag: "system"
              level: INFO
              format: "Reset value hour, starting next hour"

      # reset daily value and set yesterday value
      - seconds: 0
        minutes: 0
        hours: 0
        then:
          - lambda: |-
             id(yesterday_value)=id(daily_value);
             id(wateryesterday).publish_state(id(yesterday_value));
             id(daily_value)=0.00;
             id(waterday).publish_state(id(daily_value));
          - logger.log:
              tag: "system"
              level: INFO
              format: "Set yesterday value and reset value daily, starting new day"

      # reset weekly value, start new week
      - seconds: 0
        minutes: 0
        hours: 0
        days_of_week: MON
        then:
          - globals.set:
              id: week_value
              value: "0.00"
          - lambda: id(waterweek).publish_state(id(week_value));
          - logger.log:
              tag: "system"
              level: INFO
              format: "Reset value weekly, starting new week"

      # new year, reset yearly value
      - seconds: 0
        minutes: 0
        hours: 0
        days_of_month: 1
        months: JAN
        then:
          - globals.set:
              id: year_value
              value: "0.00"
          - lambda: id(wateryear).publish_state(id(year_value));
          - logger.log:
              tag: "system"
              level: INFO
              format: "Reset value yearly, starting new year"

## ---------------------------------------------------
## COMPONENT HTTP (optional)
## Prepare for sending HTTP requests
## ---------------------------------------------------
http_request:
  verify_ssl: false
  id: http_request_data
  useragent: ${service}
  timeout: 10s

## ---------------------------------------------------
## COMPONENT SCRIPTS
## ---------------------------------------------------
script:

  # id(set_status_message).execute();
  - id: set_status_message
    then:
        - lambda: |-
            int msgcode = int(id(cc1101_state));
            std::string message = id(cc1101_state_message)[msgcode];
            ESP_LOGD("wmbus", "cc1101 state message: %s, error code: %d", message.c_str(), msgcode);
            id(watermeter_status_message).publish_state(message);

  # id(post_device_state).execute();
  - id: post_device_state
    then:
      - if:
          condition:
            lambda: return "${service_enabled} =='true'";
          then:
            - logger.log:
                tag: "system"
                level: INFO
                format: "Post new data to the ${service_url}${device_name_short}, service enabled: ${service_enabled}"
            - http_request.post:
                url: "${service_url}/${device_name_short}"
                #verify_ssl: false
                #url: "http://192.168.0.231"
                headers:
                  Content-Type: application/json
                json: |-
                  root["device"] = "${device_name_short}";
                  root["waterdisplay"] = id(waterdisplay).state;
                  root["current"] = id(id(watercurrent)).state;
                  root["hour"] = id(waterhour).state;
                  root["day"] = id(waterday).state;
                  root["yesterday"] = id(wateryesterday).state;
                  root["week"] = id(waterweek).state;
                  root["month"] = id(watermonth).state;
                  root["lastmonth"] = id(waterhour).state;
                  root["year"] = id(wateryear).state;
                  root["bootcounter"] = id(bootcounter).state;
                  root["version"] = "${device_name_short} ${appversion}";
                  root["time"] = id(time_sntp).now().strftime("%Y-%m-%d %H:%M:%S");
                on_response:
                  then:
                    - lambda: |-
                        if (response->status_code == 200) {
                           ESP_LOGI ("system", "HTTP POST o.k");
                        } else {
                            ESP_LOGI ("system", "HTTP POST failed");
                        }

## ------------------------------------------------------------------
##           WMBUS CC1101 --> ESP32 az-delivery-devkit-v4
## ------------------------------------------------------------------
##
##
##                                                               o 1 (3.3V)
##                                                               |
##   ╭――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――o―╮
##   |                                                             |
##   |                          EP32                               |
## - | 5v               az-delivery-devkit-v4                      | -- ANT
##   |                                                             |
##   |                          16 17 5  18 19               23    |
##   ╰――x――x――x――x――x――x――x――x――o――x――o――o――o――o――o――o――o――o――o――o―╯
##                              |  |  |  |  |                 |   |
##                              o  |  |  o  |                 |   ╰-o - 2 (GND)
##                              7  o  |  4  o                 o
##                            GDO0 6  | CLK 5                 3
##                               GD02 o    MISO              M0SI
##                                    8
##                                   CSN
##
## ------------------------------------------------------------------
wmbus:
  mosi_pin: GPIO23  ## SI:   braun   3: MOSI Attached to Hardware SPI controller MOSI SPI Interface
  miso_pin: GPIO19  ## SO:   grün    5: MISO Attached to Hardware SPI controller MISO SPI Interface
  clk_pin: GPIO18   ## SCLK: violett 4: SCK  Attached to Hardware SPI controller CLK
  cs_pin: GPIO05    ## CSN:  orange  8: CSN  Attached to Hardware SPI controller
  gdo0_pin: GPIO16  ## GD00: gelb    7: RX Clock output. High Impedance !
  gdo2_pin: GPIO17  ## GD02: weiss   6: TX FIFO status signals. High Impedance !

  # log_unknown (Optional): Show telegrams from not configured meters in log. Defaults to False
  log_unknown: false

  ## -------------------------------------------------
  ## Using wmbusmeters i a pipe (optional)
  ## uncomment for using
  ## -------------------------------------------------
  # clients:
  #  - name: "wmbusmeters"
  #    ip_address: !secret wmbusmeter_host
  #    port: 7227
  #    format: rtlwMBus
  #    transport: UDP

  ## -------------------------------------------------
  ## setting: wmbusmeters.conf on wbusmeters server
  ## -------------------------------------------------
  ## loglevel: normal
  ##  device: rtlwmbus:CMD(nc -lku 7227)
  ##donotprobe: /dev/ttyAMA0
  ##logtelegrams: false
  ##format: json
  ##logfile: /dev/stdout
  ##shell: /wmbusmeters/mosquitto_pub.sh "wmbusmeters/$METER_NAME" "$METER_JSON"

  ## -------------------------------------------------
  ## led blink mode (optional) xx = PIN
  ## -------------------------------------------------
  # led_pin: GPIOxx
  # led_blink_time: "100ms"

## ---------------------------------------------------
## BINARY SENSOR
## ---------------------------------------------------
binary_sensor:

  # simulate led state (updated by id: "waterdisplay")
  - platform: template
    name: "Wasseruhr Status Led"
    id: statusled
    icon: mdi:led-outline
    entity_category: "diagnostic"
    lambda: "return id(current_value) > 0;"

## ---------------------------------------------------
## SENSORS
## ---------------------------------------------------
sensor:

  - platform: wmbus

    # Meter ID (usually from sticker). Can be specified as decimal or hex.
    # only HEX is working for my watermeter !
    # see: https://github.com/SzczepanLeon/esphome-components/issues/6
    # edit watermeterid in the secrets file
    # add_prefix: enable/disable add watermeterid to lqi, rssi, total_water_m3
    meter_id: !secret watermeterId
    type: izar
    add_prefix: false

    # The LQI value reported by the CC1101 is a 7 bit unsigned number with a range from 0 to 127.
    # Note that a lower value indicates a better link.
    # The LQI of a received packet will be bad (higher number) when there is lot of interference.
    lqi:
      id: wmbus_cc1101_lqi
      name: "${friendly_name} CC1101 LQI"
      entity_category: "diagnostic"
      unit_of_measurement: "lqi"
      state_class: "measurement"

    # The RSSI value reported by the CC1101 is a 8 bit signed number with an effective
    # range from -138 dBm to -10.5 dBm when the CC1101 is operating around 868 MHz.
    # RSSI stands for received signal strength (power) indication (in dBm).
    # A higher value indicates higher power. (internal only) see id: cc1101_rssi
    rssi:
      id: wmbus_cc1101_rssi
      name: "${friendly_name} CC1101 RSSI"
      filters:
        - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
      unit_of_measurement: "%"
      entity_category: "diagnostic"
      state_class: "measurement"
      icon: mdi:rss

    # get the total watermter m3 from the wmbus telegram, log the timestamp
    # for the last reading  and calculates the statitics value
    # and update all sensors: last_value, watercurrent, hour_value, daily_value
    # week_value, month_value, year_value and watermeter_lastupdate
    total_water_m3:
      id: "waterdisplay"
      name: "Wasseruhr Anzeige"
      unit_of_measurement: "m³"
      state_class: total_increasing
      device_class: "water"
      accuracy_decimals: 3
      icon: mdi:counter

      # Send the value periodically with the specified time interval.
      # If the sensor value changes during the interval the interval will not reset.
      # The last value of the sensor will be sent. 60s means, that every minute the
      # last state will be published.
      # The IZAR Watermeter will publish data all 8s (see transmit_period_s),
      # but we need this only evers minute.
      # filters:
      #   - heartbeat: 60s

      # update and calulatet all watermeter sensor data values
      on_value:
        then:
          - lambda: |-
              if ((id(last_value) > 0.00) and (id(waterdisplay).state)>(id(last_value)) ) {
                id(cc1101_state) = 2;
                ESP_LOGI("wmbus", "Water Display value: %.3f, last value: %.3f", id(waterdisplay).state, id(last_value));
                id(current_value) = float(id(waterdisplay).state-id(last_value)) * 1000.00;
                id(watercurrent).publish_state(id(current_value));
                id(hour_value)+=id(current_value);
                id(waterhour).publish_state(id(hour_value));
                id(daily_value)+=id(current_value);
                id(waterday).publish_state(id(daily_value));
                id(week_value)+=id(current_value);
                id(waterweek).publish_state(id(week_value));
                id(year_value)+=id(current_value);
                id(wateryear).publish_state(id(year_value));
                ESP_LOGD("wmbus", "Set current value to %.3f litre and publish the data", id(current_value));
                if ( ${service_enabled} == true){
                  id(post_device_state).execute();
                }else{
                  ESP_LOGD("wmbus", "Data Service to host disabled");
                }
              }else{
                id(current_value) = 0.00;
                id(cc1101_state) = 1;
                id(watercurrent).publish_state(id(current_value));
                ESP_LOGI("wmbus", "Reset current value to: %.3f, Waterdisplay value: %.3f, last value: %.3f", id(current_value), id(waterdisplay).state, id(last_value));
              }
              id(last_value)=id(waterdisplay).state;

          # update the watermeter_lastupdate timestamp for the last waterdisplay state
          - text_sensor.template.publish:
              id: watermeter_lastupdate
              state: !lambda return id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z");

          # update watermeter_read_timeout the reading timeout for the watermeter display
          - sensor.template.publish:
              id: watermeter_read_timeout
              state: !lambda |-
                int time_used = ( millis() - id(send_millisecond) );
                ESP_LOGD("wmbus", "Diff millisecond is: %d", time_used);
                id(send_millisecond) = millis();
                return float(time_used)/1000;

          # update the watermeter status
          - script.execute: set_status_message

          # update the status led (statusled)
          - binary_sensor.template.publish:
              id: statusled
              state: !lambda "return id(current_value) > 0;"

    # water current month (wM-Bus v2.1.4)
    current_month_total_water_l:
      name: Wasser Monat
      id: "watermonth"
      accuracy_decimals: 2
      unit_of_measurement: "L"
      icon: mdi:water-outline
      state_class: total_increasing
      device_class: "water"

    # get the last month total watermter m3 from the wmbus telegram  (wM-Bus 2.1.10)
    last_month_total_water_m3:
      name: "Wasseruhr Anzeige letzter Monat"
      id: "waterdisplay_lastmonth"
      unit_of_measurement: "m³"
      state_class: total_increasing
      device_class: "water"
      accuracy_decimals: 3
      icon: mdi:counter

    # get the battery life time (wM-Bus v2.1.4)
    remaining_battery_life_y:
      name: "Wasseruhr Batterielebensdauer"
      id: "watermeter_batterie"
      accuracy_decimals: 2
      unit_of_measurement: "Jahre"
      state_class: "measurement"
      entity_category: "diagnostic"
      icon: mdi:battery

    # get the last transmit periode (wM-Bus v2.1.4)
    transmit_period_s:
      name: "Wasseruhr Update Intervall"
      id: "watermeter_transmit_periode"
      unit_of_measurement: "sec"
      state_class: "measurement"
      accuracy_decimals: 2
      entity_category: "diagnostic"
      icon: mdi:timelapse

    ## get the current watermeter alarms and publish the text message (wM-Bus 2.1.10)
    ## see: id: watermeter_alarm_message
    current_alarms:
      id: "watermeter_current_alarms"
      name: "Wasseruhr Alarm Code"
      entity_category: "diagnostic"
      icon: mdi:message-alert-outline
      on_value:
        then:
          - lambda: |-
              int error_code = int(x);
              std::string message = "";
              if(error_code==0){
                  message = id(alarm_error_text)[error_code];
                  id(watermeter_alarm_message).publish_state(message);
                  ESP_LOGD("wmbus", "Alarm message: %s, error code: %d", message, error_code);
              }else{
                for (int i = 1; i < 10; ++i) {
                  if (error_code & (1 << i)) {
                    if (!message.empty()) {
                      message += ", ";
                    }
                    message += id(alarm_error_text)[i];
                  }
                }
                id(watermeter_alarm_message).publish_state(message);
                ESP_LOGW("wmbus", "WARNING Alarm message: %s, error code: %d", message.c_str(), error_code);
                id(watermeter_alarm_timestamp).publish_state(id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z").c_str());
              }

    ## get the prevois watermeter alarms and publish the text message (wM-Bus 2.1.10)
    ## see: id: watermeter_alarm_perv_message
    previous_alarms:
      id: "watermeter_previous_alarms"
      name: "Wasseruhr Alarm Code voriger"
      icon: mdi:message-alert
      entity_category: "diagnostic"
      on_value:
        then:
          - lambda: |-
              int error_code = int(x);
              std::string message = "";
              if(error_code==0){
                  message = id(alarm_error_text)[error_code];
                  id(watermeter_alarm_message).publish_state(message);
                  ESP_LOGD("wmbus", "Alarm message: %s, error code: %d", message, error_code);
              }else{
                for (int i = 1; i < 10; ++i) {
                  if (error_code & (1 << i)) {
                    if (!message.empty()) {
                      message += ", ";
                    }
                    message += id(alarm_error_text)[i];
                  }
                }
                ESP_LOGW("wmbus", "WARNING Alarm message: %s, error code: %d", message.c_str(), error_code);
                id(watermeter_alarm_timestamp).publish_state(id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z").c_str());
              }
              id(watermeter_alarm_perv_message).publish_state(message);
              if(id(watermeter_alarm_timestamp).has_state() == false) {
                id(watermeter_alarm_timestamp).publish_state("--");
              }

  # water current (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Aktuell
    id: "watercurrent"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-well
    state_class: "measurement"
    device_class: "water"
    lambda: return (id(current_value));

  # water current hour (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Stunde
    id: "waterhour"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-well-outline
    state_class: total_increasing
    device_class: "water"
    lambda: return (id(hour_value));

  # water today (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Tag
    id: "waterday"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-well-outline
    device_class: "water"
    state_class: total_increasing
    lambda: return (id(daily_value));

  # water yesterday (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Gestern
    id: "wateryesterday"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-well-outline
    device_class: "water"
    state_class: total_increasing
    lambda: return (id(yesterday_value));

  # water current week (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Woche
    id: "waterweek"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-well-outline
    device_class: "water"
    state_class: total_increasing
    lambda: return (id(week_value));

  # water last month (updated by id: "waterdisplay")
  - platform: template
    name: Wasser letzer Monat
    id: "waterlastmonth"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: total_increasing
    device_class: "water"
    lambda: return (id(lastmonth_value));

  # water current year (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Jahr
    id: "wateryear"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: total_increasing
    device_class: "water"
    lambda: return (id(year_value));

  # service call delay (updated by id: "waterdisplay")
  - platform: template
    name: Wasseruhr Daten Intervall
    id: watermeter_read_timeout
    icon: mdi:clock-start
    accuracy_decimals: 2
    unit_of_measurement: "sec"
    state_class: "measurement"
    entity_category: "diagnostic"

  # Wifi quality RSSI (%)
  - platform: wifi_signal
    name: "${friendly_name} WLAN Signal"
    id: wifi_signal_db
    update_interval: 60s
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    entity_category: "diagnostic"
    unit_of_measurement: "%"

  # device internal temperature (only webview)
  - platform: internal_temperature
    name: Device Internal Temperature
    id: device_internal_temperature
    icon: mdi:thermometer-lines
    state_class: "measurement"
    update_interval: 60s
    entity_category: "diagnostic"
    disabled_by_default: true

  # the current size of free heap memory.
  - platform: template
    name: ${friendly_name} Free Heap Min
    id: sysfreemapmin
    icon: mdi:counter
    lambda: return {static_cast<float>(esp_get_minimum_free_heap_size())};
    unit_of_measurement: B
    update_interval: 2s
    entity_category: "diagnostic"

  # Minimum free heap ever available
  - platform: template
    name: ${friendly_name} Free Heap
    id: sysfreeheap
    icon: mdi:counter
    lambda: return {static_cast<float>(esp_get_free_heap_size())};
    unit_of_measurement: B
    update_interval: 2s
    entity_category: "diagnostic"

  # Free memory
  - platform: template
    name: "${friendly_name} - Free Memory"
    # lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL) / 1024;
    lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
    unit_of_measurement: "B"
    state_class: measurement

  # Uptime device in hours
  - platform: uptime
    name: "${friendly_name} Online seit"
    id: uptime_human
    icon: mdi:clock-start
    filters:
      - lambda: return x / 3600;
    unit_of_measurement: "h"
    entity_category: "diagnostic"
    state_class: "measurement"
    accuracy_decimals: 2

  # device boot counter by device boot
  - platform: template
    name: "${friendly_name} Boot counter"
    id: bootcounter
    icon: mdi:counter
    accuracy_decimals: 0
    state_class: "measurement"
    entity_category: "diagnostic"
    lambda: return (id(boot_counter));

## ---------------------------------------------------
## SWITCHES
## ---------------------------------------------------
switch:
  # reset boot counter value
  - platform: template
    name: "${friendly_name} Boot Counter Reset"
    icon: mdi:lock-reset
    turn_on_action:
      then:
        - lambda: |-
            id(boot_counter) = 0;
            id(bootcounter).publish_state(id(boot_counter));
        - logger.log:
            level: WARN
            tag: "system"
            format: "${device_name_short} reset boot counter o.k!"
        - component.update: bootcounter

  # reset all global vars
  - platform: template
    name: "Wasseruhr Reset values"
    icon: mdi:lock-reset
    turn_on_action:
      then:
        - lambda: |-
            id(last_value) = 0.00;
            id(boot_counter) = 0;
            id(bootcounter).publish_state(id(boot_counter));
            id(current_value) = 0.00;
            id(watercurrent).publish_state(id(current_value));
            id(hour_value) = 0.00;
            id(waterhour).publish_state(id(hour_value));
            id(daily_value) = 0.00;
            id(waterday).publish_state(id(daily_value));
            id(yesterday_value) = 0.00;
            id(wateryesterday).publish_state(id(yesterday_value));
            id(week_value) = 0.00;
            id(waterweek).publish_state(id(week_value));
            id(lastmonth_value) = 0.00;
            id(waterlastmonth).publish_state(id(lastmonth_value));
            id(year_value) = 0.00;
            id(wateryear).publish_state(id(year_value));
        - logger.log:
            level: INFO
            tag: "system"
            format: "all values reset!"

  # restarts the device
  - platform: restart
    name: "${friendly_name} Restart"
    id: restart_switch
    icon: mdi:restart

## ---------------------------------------------------
## TEXT SENSOR
## ---------------------------------------------------
text_sensor:

  # watermeter status message (updated by script: set_status_message)
  - platform: template
    name: "Wasseruhr Status Info"
    id: watermeter_status_message
    icon: mdi:bell
    entity_category: "diagnostic"

  # watermeter alarm message (updated by id: current_alarms)
  - platform: template
    name: "Wasseruhr Alarm"
    id: watermeter_alarm_message
    icon: mdi:alarm-light
    entity_category: "diagnostic"

  # watermeter previous alarm message (updated by id: current_prev_alarms)
  - platform: template
    name: "Wasseruhr Alarm voriger"
    id: watermeter_alarm_perv_message
    icon: mdi:alarm-light
    entity_category: "diagnostic"

  # watermeter alarm timestamp (updated by id: current_alarms)
  - platform: template
    name: "Wasseruhr Alarm Zeit"
    id: watermeter_alarm_timestamp
    icon: mdi:alarm-light
    entity_category: "diagnostic"

  # optional device version (only for webserver)
  - platform: version
    name: "${friendly_name} ESPHome Version"
    icon: mdi:application-cog-outline
    id: appver
    hide_timestamp: true
    disabled_by_default: true

  # Last boot timestamp (updated by device boot)
  - platform: template
    name: "Device Last Boot"
    disabled_by_default: true
    id: device_lastBoot_time
    icon: mdi:clock-start

  # waterdisplay timestamp last update (updated by id: "waterdisplay")
  - platform: template
    name: "${friendly_name} Timestamp"
    id: watermeter_lastupdate
    icon: mdi:clock-start
    entity_category: "diagnostic"

  # optional device timestamp (only for webserver)
  - platform: template
    id: systime
    disabled_by_default: true
    icon: mdi:clock-start
    lambda: return id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z");

  # connected to ssid (only for webserver)
  - platform: wifi_info
    ssid:
      name: ${friendly_name} WLAN SSID
      id: wlan_ssid
      disabled_by_default: true
      icon: mdi:wifi-settings

  # simple rest get message for all watermeter data
  # (disable this if you do not need rest service)
  - platform: template
    id: watermeterdata
    internal: true
    disabled_by_default: true
    lambda: |-
      char buf[128];
      sprintf(buf, "%.3f|%.3f|%.3f|%.3f|%.3f|%.3f|%.3f|%.3f|%.3f|%s",
             id(waterdisplay).state,
             id(current_value),
             id(hour_value),
             id(daily_value),
             id(yesterday_value),
             id(week_value),
             id(watermonth).state,
             id(lastmonth_value),
             id(year_value),
             id(systime).state.c_str()
             );
      std::string s = buf;
      return s;

Thank you very much for every help i could receive.

zibous commented 2 weeks ago

you can try this version

## ---------------------------------------------------------------------------
## WMBUS METER az-delivery-devkit-v4 + CC1101 for Diehl IZAR RC 868 I R4 PL
## Hardware: ESP32 240MHz, 520KB RAM, 4MB Flash
##
## This version shows data from the defined watermeter and
## uses the watermeterID (HEX) from the secrets.yaml file.
##
## Usage:
##     + Using Homassistant API (discovery + devices)
##     + Using the last wM-Bus component
##     + Using wmbusmeters i a pipe (optional)
##
##     + REST:  curl -i http://water-meter-esp.local/text_sensor/watermeterdata
##              curl -i curl -i http://water-meter-esp.local/sensor/wasseruhr_anzeige
##
##
## ---------------------------------------------------------------------------
substitutions:

  ## device settings
  hostname: "water-meter-esp"
  friendly_name: "Wasseruhr"
  device_description: "Production 2024: Wasserzähler ESP32, CUL - CC1101, IZAR module (Diehl IZAR RC 868 I R4 PL (SzczepanLeon) my Watermeter"

  # The format of the name should be author_name.project_name.
  projectname: "Peter Siebler.Diehl IZAR RC 868"
  appversion: "Diehl IZAR RC 868 v2.1.2 (wm-esp32.yaml)"
  hardware: "ESP32_Devkit_V4"
  location: "Heizraum"

  ## logger settings
  log_level: "INFO" # not that logging need memory, so in production mode use "WARN"
  log_wmbus: "ERROR" # Loglevel for wmbus meters component
  log_baudrate: "0" # use 0 to disable serial UART port logging.

  # The built-in LED on the AZ-Delivery DevKit V4 is connected to GPIO 2.
  led_internal: "GPIO2"

## -----------------------------------------------------------------
## HARDWARE az-delivery-devkit-v4,ESP32 240MHz, 520KB RAM, 4MB Flash
## -----------------------------------------------------------------
esp32:
  board: az-delivery-devkit-v4
  framework:
    type: arduino

# Customize the frequency in which data is flushed to the flash.
preferences:
  flash_write_interval: 10min

## ----------------------------------------------------------------
## APPLICATION ESPHOME
## ----------------------------------------------------------------
esphome:
  name: ${hostname}
  build_path: ./build/${hostname}
  comment: ${device_description}
  on_boot:
    then:
      - globals.set:
          id: boot_counter
          value: !lambda "return id(boot_counter)+=1;"
      - globals.set:
          id: send_millisecond
          value: !lambda "return millis();"
      - logger.log:
          level: WARN
          tag: "system"
          format: "BOOTMESSAGE:${hostname} API is connected, Device ready!"
      - component.update: bootcounter
      - light.turn_off: internal_led

  on_shutdown:
    then:
      - logger.log:
          level: ERROR
          tag: "system"
          format: "BOOTMESSAGE:${hostname} is down!"

  project:
    # This allows creators to add the project name and version to the compiled code.
    # It is currently only exposed via the logger, mDNS and the device_info response
    # via the native API. The format of the name should be author_name.project_name.
    name: ${projectname}
    version: ${appversion}

  area: ${location}
  platformio_options: {}
  includes: []
  libraries: []
  name_add_mac_suffix: false
  # minimum version of ESPHome required to compile.
  min_version: 2024.6.6

## ------------------------------------------------------------------
## EXTERNAL COMPONENTS
## https://esphome.io/components/external_components.html
## ------------------------------------------------------------------
external_components:
  # uses the version 3.2.3  not the latest 4.0 version from SzczepanLeon (github)
  # https://github.com/SzczepanLeon/esphome-components
  # You can make ESPHome check the repository every time by setting this option to 0s
  - source: source: github://SzczepanLeon/esphome-components@3.2.3
    refresh: 0s
    components: [wmbus]

## ------------------------------------------------------------------
## Global variables
## https://esphome.io/components/globals.html
## ------------------------------------------------------------------
globals:

  - id: boot_counter
    type: int
    restore_value: yes
    initial_value: "0"

  - id: last_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: current_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: hour_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: daily_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: yesterday_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: week_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: lastmonth_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: year_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: send_millisecond
    type: int
    restore_value: no
    initial_value: "0"

  - id: cc1101_state
    type: int
    restore_value: no
    initial_value: "0"

  - id: alarm_error_text
    type: std::vector<std::string>
    restore_value: no
    # initial_value: '{"no error", "general_alarm","leakage","meter_blocked","back_flow","underflow","overflow","submarine","sensor_fraud","mechanical_fraud"}'
    initial_value: '{"Keiner", "Fehler","Zähler undicht","Zähler blockiert","Wasser Rückfluss","Wasser Unterlauf","Wasser Überlauf","Überschwemung","Sensor Fehler", "Mechanischer Fehler"}'

  - id: cc1101_state_message
    type: std::vector<std::string>
    restore_value: no
    # initial_value: '{"Init", "Waiting", "Recived Data", "Ready", "Error"}'
    initial_value: '{"Init", "Warte auf Daten", "Daten empfangen", "Ready", "Error"}'

## ------------------------------------------------------------------
## COMPONENT LOGGER
## https://esphome.io/components/logger.html
## ------------------------------------------------------------------
logger:
  id: appslogger
  level: ${log_level}
  baud_rate: ${log_baudrate}
  logs:
    wmbus: ${log_wmbus}
    wMBus-lib: ${log_wmbus}
    sensor: WARN
    sensor.filter: WARN
    text_sensor: WARN
    api.service: ERROR
    json: ERROR
    mqtt: WARN
    scheduler: ERROR
    internal_temperature: ERROR
    wifi: WARN
    component: ERROR
    api: WARN

## ------------------------------------------------------------------
## COMPONENT WIFI
## https://esphome.io/components/wifi.html
## ------------------------------------------------------------------
wifi:

  networks:

    # default wifi smarthome iot
    - ssid: !secret wifi_ssid
      password: !secret wifi_password
      priority: 100.00

    # fallback 1: wifi 2.4Ghz + 5GHz
    - ssid: !secret ssid2_name
      password: !secret ssid2_pswd
      priority: 10.0

    # fallback 2: wifi 2.4Ghz + 5GHz
    - ssid: !secret ssid3_name
      password: !secret ssid3_pswd
      priority: 20.0

    # fallback 3: wifi 2.4Ghz
    - ssid: !secret ssid4_name
      password: !secret ssid4_pswd
      priority: 10.0

  on_connect:
    - logger.log:
        level: INFO
        tag: "WIFI-INFO"
        format: "Device has connected to wifi"

  on_disconnect:
    - logger.log:
        level: WARN
        tag: "WIFI-INFO"
        format: "Client disconnected from wifi, try recconect"

  domain: !secret domain
  reboot_timeout: 5min

  power_save_mode: none # Optionen: none 1.5W, light 1.43W, high 1.28W
  output_power: 12db # reduce power (default is 20db)  10/15 ->  0,92W
  fast_connect: false
  passive_scan: false
  enable_on_boot: true

# ------------------------------------------------------------------
## COMPONENT Captive Portal
## ------------------------------------------------------------------
## The captive portal component in ESPHome is a fallback mechanism
## for when connecting to the configured WiFi fails.
## https://esphome.io/components/captive_portal.html
## ------------------------------------------------------------------
captive_portal:

## ---------------------------------------------------
## mDNS Component
## https://esphome.io/components/mdns.html
## ---------------------------------------------------
mdns:
  # Both Home Assistant and the ESPHome dashboard use mDNS to identify the IP address
  # of all ESPHome nodes on the network. If mDNS is disabled, they will no longer
  # be able to automatically find your devices.
  disabled: false

## ------------------------------------------------------------------
## COMPONENT Over-the-Air Updates
## https://esphome.io/components/ota/#over-the-air-updates
## ------------------------------------------------------------------
ota:
  platform: esphome
  password: !secret ota_pswd
  on_begin:
    then:
      - logger.log:
          format: "OTA Start"
          tag: "OTA"
          level: WARN
  on_progress:
    then:
      - logger.log:
          level: WARN
          tag: "OTA"
          format: "OTA progress %0.1f%%"
          args: ["x"]
  on_end:
    then:
      - logger.log:
          format: "OTA End"
          tag: "OTA"
          level: WARN
  on_error:
    then:
      - logger.log:
          format: "OTA update error %d"
          tag: "OTA"
          level: ERROR
          args: ["x"]

## ------------------------------------------------------------------
## COMPONENT WEBSERVER
## The web_server component creates a simple web server on the node
## that can be accessed through any browser and a simple REST API.
## https://esphome.io/components/web_server.html
## ------------------------------------------------------------------
web_server:
  port: 80
  version: 3
  local: false
  js_url: !secret webserver3_jsurl

## ---------------------------------------------------
## COMPONENT Home Assistant API
## https://esphome.io/components/api.html
## Homeassistant service call (all values in liter):
## ---------------------------------------------------
## service: esphome.water_meter_esp_set_watermeter_esp_data
## data:
##   water_val_hour: 0.00
##   water_val_day: 167.00
##   water_val_yesterday: 240.35
##   water_val_week: 901.00
##   water_val_year: 33143.00
##   water_val_lastmonth: 7580.25
## ---------------------------------------------------
api:
  id: espapi_wmbus_esp32
  port: 6053
  reboot_timeout: 0s
  # https://esphome.io/components/api.html?highlight=api
  encryption:
    key: "inH49O9jBeK5yTGb1X2g4x4V/1aS6YKUpu3Vu277fDgw="
  on_client_connected:
    - logger.log:
        format: "Client %s connected to API with IP %s, say hello"
        args: ["client_info.c_str()", "client_address.c_str()"]
  on_client_disconnected:
    - logger.log:
        format: "Client %s disconnected to API with IP %s, say goodbye"
        args: ["client_info.c_str()", "client_address.c_str()"]

  # service call from homeassistant to set the data
  services:
    - service: set_watermeter_esp_data
      variables:
        water_val_hour: float
        water_val_day: float
        water_val_yesterday: float
        water_val_week: float
        water_val_year: float
        water_val_lastmonth: float
      then:
        - logger.log:
            tag: "system"
            format: "Try to set new values: hour: %.3f, day: %.3f, yesterday: %.3f, week: %.3f, last month: %.3f, year: %.3f"
            level: INFO
            args:
              [
                "water_val_hour",
                "water_val_day",
                "water_val_yesterday",
                "id(week_value)",
                "id(lastmonth_value)",
                "id(year_value)",
              ]
        # new value for water hourly
        - globals.set:
            id: hour_value
            value: !lambda |-
              if((water_val_hour) and (water_val_hour)>0.001){
                ESP_LOGD("system", "Set hourly value to: %f", water_val_hour);
                return (water_val_hour);
              }else{
                ESP_LOGD("system", "Skip setting hourly value");
                return id(hour_value);
              };
              id(waterhour).publish_state(id(hour_value));
        - component.update: waterhour
        # new value for water daily
        - globals.set:
            id: daily_value
            value: !lambda |-
              if((water_val_day) and (water_val_day)>0.001){
                ESP_LOGD("system", "Set daily value to: %f", water_val_day);
                return (water_val_day);
              }else{
                ESP_LOGD("system", "Skip setting hourly value");
                return id(daily_value);
              };
              id(waterday).publish_state(id(daily_value));
        - component.update: waterday
        # new value for water yesterday
        - globals.set:
            id: yesterday_value
            value: !lambda |-
              if((water_val_yesterday) and (water_val_yesterday)>0.001){
                ESP_LOGD("system", "Set yesterday value to: %f", water_val_yesterday);
                return (water_val_yesterday);
              }else{
                ESP_LOGD("system", "Skip setting yesterday value");
                return id(yesterday_value);
              };
              id(wateryesterday).publish_state(id(yesterday_value));
        - component.update: wateryesterday
        # new value for water weekly
        - globals.set:
            id: week_value
            value: !lambda |-
              if((water_val_week) and (water_val_week)>0.001){
                ESP_LOGD("system", "Set weekly value to: %f", water_val_week);
                return (water_val_week);
              }else{
                ESP_LOGD("system", "Skip setting weekly value");
                return id(week_value);
              };
              id(waterweek).publish_state(id(week_value));
        - component.update: waterweek
        # new value for water lastmonth
        - globals.set:
            id: lastmonth_value
            value: !lambda |-
              if((water_val_lastmonth) and (water_val_lastmonth)>0.001){
                ESP_LOGD("system", "Set last month value to: %f", water_val_lastmonth);
                return (water_val_lastmonth);
              }else{
                ESP_LOGD("system", "Skip setting last month value");
                return id(lastmonth_value);
              };
              id(waterlastmonth).publish_state(id(lastmonth_value));
        - component.update: waterlastmonth
        # new value for water yearly
        - globals.set:
            id: year_value
            value: !lambda |-
              if((water_val_year) and (water_val_year)>0.001){
                ESP_LOGD("system", "Set last yearly value to: %f", water_val_year);
                return (water_val_year);
              }else{
                ESP_LOGD("system", "Skip setting last yearly value");
                return id(year_value);
              };
              id(wateryear).publish_state(id(year_value));
        - component.update: wateryear
        - logger.log:
            tag: "system"
            format: "All new Values set: hour: %.3f, day: %.3f, week: %.3f, last month: %.3f, year: %.3f"
            level: INFO
            args:
              [
                "id(hour_value)",
                "id(daily_value)",
                "id(week_value)",
                "id(lastmonth_value)",
                "id(year_value)",
              ]

## ---------------------------------------------------
## SNTP Time server
## https://esphome.io/components/time/sntp.html
## ---------------------------------------------------
time:
  - platform: sntp
    id: time_sntp
    timezone: Europe/Berlin
    servers:
      - !secret local_sntp
      - 0.at.pool.ntp.org
      - 0.pool.ntp.org
    on_time_sync:
      # Components should trigger on_time_sync when they update the system clock.
      then:
        - if:
            condition:
              lambda: 'return id(device_lastBoot_time).state == "";'
            then:
              - text_sensor.template.publish:
                  id: device_lastBoot_time
                  state: !lambda return id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z");
              - component.update: systime
              - component.update: watermeter_lastupdate

        - logger.log:
            level: WARN
            tag: "system"
            format: "Synchronized sntp clock"
        - script.execute: set_status_message

    on_time:
      # check cc1101 telegram state message every 30s
      - seconds: 30
        then:
          - script.execute: set_status_message

      # reset hourly value
      - seconds: 0
        minutes: 0
        then:
          - globals.set:
              id: hour_value
              value: "0.00"
          - lambda: id(waterhour).publish_state(id(hour_value));
          - logger.log:
              tag: "system"
              level: INFO
              format: "Reset value hour, starting next hour"

      # reset daily value and set yesterday value
      - seconds: 0
        minutes: 0
        hours: 0
        then:
          - lambda: |-
              id(yesterday_value)=id(daily_value);
              id(wateryesterday).publish_state(id(yesterday_value));
              id(daily_value)=0.00;
              id(waterday).publish_state(id(daily_value));
          - logger.log:
              tag: "system"
              level: INFO
              format: "Set yesterday value and reset value daily, starting new day"

      # reset weekly value, start new week
      - seconds: 0
        minutes: 0
        hours: 0
        days_of_week: MON
        then:
          - globals.set:
              id: week_value
              value: "0.00"
          - lambda: id(waterweek).publish_state(id(week_value));
          - logger.log:
              tag: "system"
              level: INFO
              format: "Reset value weekly, starting new week"

      # new year, reset yearly value
      - seconds: 0
        minutes: 0
        hours: 0
        days_of_month: 1
        months: JAN
        then:
          - globals.set:
              id: year_value
              value: "0.00"
          - lambda: id(wateryear).publish_state(id(year_value));
          - logger.log:
              tag: "system"
              level: INFO
              format: "Reset value yearly, starting new year"

## ---------------------------------------------------
## COMPONENT SCRIPTS
## ---------------------------------------------------
script:
  # id(set_status_message).execute();
  - id: set_status_message
    then:
      - lambda: |-
          int msgcode = int(id(cc1101_state));
          std::string message = id(cc1101_state_message)[msgcode];
          ESP_LOGD("wmbus", "cc1101 state message: %s, error code: %d", message.c_str(), msgcode);
          id(watermeter_status_message).publish_state(message);

## ---------------------------------------------------------------------------------
##                WMBUS CC1101 --> ESP32 az-delivery-devkit-v4
## ---------------------------------------------------------------------------------
##
##
##                             ╭―――――――――――――――――――――――╮
##                       GPIO6 | [ ] O  | USB |  O [ ] | 5V
##                       GPIO7 | [ ]    -------    [ ] | GPIO11
##                       GPIO8 | [ ]               [ ] | GPI010
##                      GPIO15 | [ ]               [ ] | GPIO9
##                       GPIO2 | [ ]               [ ] | GPI013
##                       GPIO0 | [ ]               [ ] | GND
##                       GPIO4 | [ ]               [ ] | GPI012
##   GDO0 (2)  ■ <----  GPIO16 | [■]               [ ] | GPI014
##   GDO2 (3)  ■ <----  GPIO17 | [■]               [ ] | GPI027
##                      GPIO05 | [ ]  ___________  [ ] | GPI026
##    CLK (5)  ■ <----  GPIO18 | [■] |           | [ ] | GPI025
##   MISO (4)  ■ <----  GPIO19 | [■] |           | [ ] | GPI033
##                         GND | [ ] |           | [ ] | GPI032
##    CSN (2)  ■ <----  GPIO21 | [■] |           | [ ] | GPI035
##                       GPIO3 | [ ] |           | [ ] | GPI034
##                       GPIO1 | [ ] |           | [ ] | GPI039
##                      GPIO22 | [ ] |           | [ ] | GPI036
##    MSOI (6) ■ <----  GPIO23 | [■] |           | [ ] | RESET
##     GND (7) ■ <----     GND | [■] |___________| [■] | 3.3V      ---> ■ 3.3V (8)
##                             ╰―――――――――――――――――――――――╯
##                                |  |  ____  ____  |
##                                |  |  |  |  |  |  |
##                                |__|__|  |__|  |__|
##
##                               INTERNAL LED: ■ GPIO2
##
##
##                              ╭――――――――――――――――――――――――――――╮
##                              │                      CSN ■ │ 1  --> ■ GPIO21
##                              │                     GDO0 ■ │ 2  --> ■ GPIO16
##                              │ ■ GND               GDO2 ■ │ 3  --> ■ GPIO17
##                              │ ■ ANT      CC1101     SO ■ │ 4  --> ■ GPIO19
##                              │ ■ GND                CLK ■ │ 5  --> ■ GPIO18
##                              │                       SI ■ │ 6  --> ■ GPIO23
##                              │                      GND ■ │ 7  --> ■ GND
##                              │                     3.3V ■ │ 8  --> ■ 3.3V
##                              ╰――――――――――――――――――――――――――――╯
##
##
##
## ---------------------------------------------------------------------------------

wmbus:
  mosi_pin: GPIO23 ## SI:   braun   3: MOSI Attached to Hardware SPI controller MOSI SPI Interface
  miso_pin: GPIO19 ## SO:   grün    5: MISO Attached to Hardware SPI controller MISO SPI Interface
  clk_pin:  GPIO18 ## SCLK: violett 4: SCK  Attached to Hardware SPI controller CLK
  cs_pin:   GPIO21 ## CSN:  orange  8: CSN  Attached to Hardware SPI controller
  gdo0_pin: GPIO16 ## GD00: gelb    7: RX Clock output. High Impedance !
  gdo2_pin: GPIO17 ## GD02: weiss   6: TX FIFO status signals. High Impedance !

  # log_unknown (Optional): Show telegrams from not configured meters in log. Defaults to True.
  log_unknown: False

## ---------------------------------------------------
## BUTTON
## ---------------------------------------------------
button:
  # reset boot counter value
  - platform: template
    name: "${friendly_name} Boot Counter Reset"
    id: btn_bc
    icon: mdi:counter
    disabled_by_default: false
    entity_category: config
    web_server_sorting_weight: 12
    on_press:
      then:
        - lambda: id(boot_counter) = 0; id(bootcounter).publish_state(id(boot_counter));
        - logger.log:
            level: WARN
            tag: "system"
            format: "${hostname} reset boot counter o.k!"
        - component.update: bootcounter

  # reset all global vars
  - platform: template
    name: "${friendly_name} Reset values"
    icon: mdi:lock-reset
    entity_category: config
    web_server_sorting_weight: 13
    on_press:
      then:
        - lambda: |-
            id(last_value) = 0.00;
            id(boot_counter) = 0;
            id(bootcounter).publish_state(id(boot_counter));
            id(current_value) = 0.00;
            id(watercurrent).publish_state(id(current_value));
            id(hour_value) = 0.00;
            id(waterhour).publish_state(id(hour_value));
            id(daily_value) = 0.00;
            id(waterday).publish_state(id(daily_value));
            id(yesterday_value) = 0.00;
            id(wateryesterday).publish_state(id(yesterday_value));
            id(week_value) = 0.00;
            id(waterweek).publish_state(id(week_value));
            id(lastmonth_value) = 0.00;
            id(waterlastmonth).publish_state(id(lastmonth_value));
            id(year_value) = 0.00;
            id(wateryear).publish_state(id(year_value));
        - logger.log:
            level: INFO
            tag: "system"
            format: "all values reset!"

  # simple button for restart
  - platform: restart
    name: ${friendly_name} Restart
    id: restart_device
    disabled_by_default: false
    entity_category: config
    icon: mdi:restart
    web_server_sorting_weight: 14

# Configure the on-board LED (GPIO 2)
output:
  - platform: gpio
    id: onboard_led
    pin:
      number: GPIO2
      ignore_strapping_warning: true

# Create a internal switch to control the on-board LED
light:
  - platform: binary
    id: internal_led
    internal: true
    output: onboard_led
    restore_mode: ALWAYS_OFF

# ----------------------------------------------------------------
# BINARY SENSOR
# https://esphome.io/components/binary_sensor/
# ----------------------------------------------------------------
binary_sensor:

  # simulate led state (updated by id: "waterdisplay")
  - platform: template
    name: "${friendly_name} Status Led"
    id: statusled
    icon: mdi:led-outline
    entity_category: "diagnostic"
    lambda: "return id(current_value) > 0;"
    web_server_sorting_weight: 19

## ---------------------------------------------------
## SENSOREN
## https://esphome.io/components/sensor/
## ---------------------------------------------------
sensor:

  - platform: wmbus

    # Meter ID (usually from sticker). Can be specified as decimal or hex.
    # --------------------------------------------------------------------
    # Meter ID only HEX is working for my watermeter !
    # 1. find the Meter ID with meter_id: "0"
    # 2. log shows the Meter ID [14:08:40][I][wmbus:060]: Using driver 'izar' for ID [0x43430778] RSSI: -63 dBm T: 1944A5117...
    # 3. change meter_id: 0x43430778
    # 4. edit watermeterid in the secrets file
    # --------------------------------------------------------------------
    # see: https://github.com/SzczepanLeon/esphome-components/issues/6
    meter_id: !secret watermeterId
    type: izar
    # add_prefix: enable/disable add watermeterid to lqi, rssi, total_water_m3
    add_prefix: false

    # The LQI value reported by the CC1101 is a 7 bit unsigned number with a range from 0 to 127.
    # Note that a lower value indicates a better link.
    # The LQI of a received packet will be bad (higher number) when there is lot of interference.
    lqi:
      id: wmbus_cc1101_lqi
      name: "${friendly_name} LQI"
      entity_category: "diagnostic"
      unit_of_measurement: dBm
      device_class: signal_strength
      state_class: "measurement"
      icon: mdi:rss
      web_server_sorting_weight: 22

    # The RSSI value reported by the CC1101 is a 8 bit signed number with an effective
    # range from -138 dBm to -10.5 dBm when the CC1101 is operating around 868 MHz.
    # RSSI stands for received signal strength (power) indication (in dBm).
    # A higher value indicates higher power. (internal only) see id: cc1101_rssi
    rssi:
      id: wmbus_cc1101_rssi
      name: "${friendly_name} RSSI"
      icon: mdi:rss
      unit_of_measurement: "Signal %"
      entity_category: "diagnostic"
      state_class: "measurement"
      device_class: ""
      web_server_sorting_weight: 23
      filters:
        - filter_out: nan
        - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);

    # get the total watermter m3 from the wmbus telegram, log the timestamp
    # for the last reading  and calculates the statitics value
    # and update all sensors: last_value, watercurrent, hour_value, daily_value
    # week_value, month_value, year_value and watermeter_lastupdate
    total_water_m3:
      id: "waterdisplay"
      name: "${friendly_name} Anzeige"
      unit_of_measurement: "m³"
      state_class: total_increasing
      device_class: "water"
      accuracy_decimals: 3
      icon: mdi:counter
      web_server_sorting_weight: 1
      # Send the value periodically with the specified time interval.
      # If the sensor value changes during the interval the interval will not reset.
      # The last value of the sensor will be sent. 60s means, that every minute the
      # last state will be published.
      # The IZAR Watermeter will publish data all 8s (see transmit_period_s),
      # but we need this only evers minute.
      # filters:
      #   - heartbeat: 60s
      # update and calculate all watermeter sensor data values
      on_value:
        then:
          - lambda: |-
              if ((id(last_value) > 0.00) and (id(waterdisplay).state)>(id(last_value)) ) {
                id(cc1101_state) = 2;
                ESP_LOGI("wmbus", "Water Display value: %.3f, last value: %.3f", id(waterdisplay).state, id(last_value));
                id(current_value) = float(id(waterdisplay).state-id(last_value)) * 1000.00;
                id(watercurrent).publish_state(id(current_value));
                id(hour_value)+=id(current_value);
                id(waterhour).publish_state(id(hour_value));
                id(daily_value)+=id(current_value);
                id(waterday).publish_state(id(daily_value));
                id(week_value)+=id(current_value);
                id(waterweek).publish_state(id(week_value));
                id(year_value)+=id(current_value);
                id(wateryear).publish_state(id(year_value));
                ESP_LOGD("wmbus", "Set current value to %.3f litre and publish the data", id(current_value));
              }else{
                id(current_value) = 0.00;
                id(cc1101_state) = 1;
                id(watercurrent).publish_state(id(current_value));
                ESP_LOGI("wmbus", "Reset current value to: %.3f, Waterdisplay value: %.3f, last value: %.3f", id(current_value), id(waterdisplay).state, id(last_value));
              }
              id(last_value)=id(waterdisplay).state;

          # calculate the water usage in percent
          - component.update: water_consumption

          # update the watermeter_lastupdate timestamp for the last waterdisplay state
          - text_sensor.template.publish:
              id: watermeter_lastupdate
              state: !lambda return id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z");

          # update watermeter_read_timeout the reading timeout for the watermeter display
          - sensor.template.publish:
              id: watermeter_read_timeout
              state: !lambda |-
                int time_used = ( millis() - id(send_millisecond) );
                ESP_LOGD("wmbus", "Diff millisecond is: %d", time_used);
                id(send_millisecond) = millis();
                return float(time_used)/1000;

          # update the watermeter status
          - script.execute: set_status_message

          # update the status led (statusled)
          - binary_sensor.template.publish:
              id: statusled
              state: !lambda "return id(current_value) > 0;"

          - light.turn_on: internal_led
          - delay: 500ms
          - light.turn_off: internal_led

    # water current month (wM-Bus)
    current_month_total_water_l:
      name: Wasser Monat
      id: "watermonth"
      accuracy_decimals: 2
      unit_of_measurement: "L"
      icon: mdi:water-outline
      state_class: total_increasing
      device_class: "water"
      web_server_sorting_weight: 7

    # get the last month total watermter m3 from the wmbus telegram  (wM-Bus)
    last_month_total_water_m3:
      name: "${friendly_name} Anzeige letzter Monat"
      id: "waterdisplay_lastmonth"
      unit_of_measurement: "m³"
      state_class: total_increasing
      device_class: "water"
      accuracy_decimals: 3
      icon: mdi:counter
      web_server_sorting_weight: 11

    # get the battery life time (wM-Bus)
    remaining_battery_life_y:
      name: "${friendly_name} Batterielebensdauer"
      id: "watermeter_batterie"
      accuracy_decimals: 2
      unit_of_measurement: "Jahre"
      state_class: "measurement"
      entity_category: "diagnostic"
      icon: mdi:battery
      web_server_sorting_weight: 21

    # get the last transmit periode (wM-Bus)
    transmit_period_s:
      name: "${friendly_name} Update Intervall"
      id: "watermeter_transmit_periode"
      unit_of_measurement: "sec"
      state_class: "measurement"
      accuracy_decimals: 2
      entity_category: "diagnostic"
      icon: mdi:timelapse
      web_server_sorting_weight: 18

    ## get the current watermeter alarms and publish the text message (wM-Bus 2.1.10)
    ## see: id: watermeter_alarm_message
    current_alarms:
      id: "watermeter_current_alarms"
      name: "${friendly_name} Alarm Code"
      entity_category: "diagnostic"
      icon: mdi:message-alert-outline
      web_server_sorting_weight: 25
      on_value:
        then:
          - lambda: |-
              int error_code = int(x);
              std::string message = "";
              if(error_code==0){
                  message = id(alarm_error_text)[error_code];
                  id(watermeter_alarm_message).publish_state(message);
                  ESP_LOGD("wmbus", "Alarm message: %s, error code: %d", message, error_code);
              }else{
                for (int i = 1; i < 10; ++i) {
                  if (error_code & (1 << i)) {
                    if (!message.empty()) {
                      message += ", ";
                    }
                    message += id(alarm_error_text)[i];
                  }
                }
                id(watermeter_alarm_message).publish_state(message);
                ESP_LOGW("wmbus", "WARNING Alarm message: %s, error code: %d", message.c_str(), error_code);
                id(watermeter_alarm_timestamp).publish_state(id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z").c_str());
              }

    ## get the prevois watermeter alarms and publish the text message (wM-Bus 2.1.10)
    ## see: id: watermeter_alarm_perv_message
    previous_alarms:
      id: "watermeter_previous_alarms"
      name: "${friendly_name} Alarm Code voriger"
      icon: mdi:message-alert
      entity_category: "diagnostic"
      web_server_sorting_weight: 27
      on_value:
        then:
          - lambda: |-
              int error_code = int(x);
              std::string message = "";
              if(error_code==0){
                  message = id(alarm_error_text)[error_code];
                  id(watermeter_alarm_message).publish_state(message);
                  ESP_LOGD("wmbus", "Alarm message: %s, error code: %d", message, error_code);
              }else{
                for (int i = 1; i < 10; ++i) {
                  if (error_code & (1 << i)) {
                    if (!message.empty()) {
                      message += ", ";
                    }
                    message += id(alarm_error_text)[i];
                  }
                }
                ESP_LOGW("wmbus", "WARNING Alarm message: %s, error code: %d", message.c_str(), error_code);
                id(watermeter_alarm_timestamp).publish_state(id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z").c_str());
              }
              id(watermeter_alarm_perv_message).publish_state(message);
              if(id(watermeter_alarm_timestamp).has_state() == false) {
                id(watermeter_alarm_timestamp).publish_state("--");
              }

  # water current (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Aktuell
    id: "watercurrent"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-circle
    device_class: "water"
    state_class: total_increasing
    lambda: return (id(current_value));
    web_server_sorting_weight: 2

  # water current hour (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Stunde
    id: "waterhour"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-circle
    state_class: total_increasing
    device_class: "water"
    lambda: return (id(hour_value));
    web_server_sorting_weight: 3

  # water today (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Tag
    id: "waterday"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-circle
    device_class: "water"
    state_class: total_increasing
    lambda: return (id(daily_value));
    web_server_sorting_weight: 4

  # water yesterday (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Gestern
    id: "wateryesterday"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-circle
    device_class: "water"
    state_class: total_increasing
    lambda: return (id(yesterday_value));
    web_server_sorting_weight: 5

  # water current week (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Woche
    id: "waterweek"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-circle
    device_class: "water"
    state_class: total_increasing
    lambda: return (id(week_value));
    web_server_sorting_weight: 6

  # water last month (updated by id: "waterdisplay")
  - platform: template
    name: Wasser letzer Monat
    id: "waterlastmonth"
    icon: mdi:water-outline
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: total_increasing
    device_class: "water"
    lambda: return (id(lastmonth_value));
    web_server_sorting_weight: 9

  # water current year (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Jahr
    id: "wateryear"
    icon: mdi:water-outline
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: total_increasing
    device_class: "water"
    lambda: return (id(year_value));
    web_server_sorting_weight: 10

  # ratio lastmonth to current month (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Verbrauch
    id: water_consumption
    web_server_sorting_weight: 11
    unit_of_measurement: "%"
    state_class: measurement
    icon: "mdi:percent"
    accuracy_decimals: 2
    lambda: |-
      if(id(waterlastmonth).state > 0.00){
        return ( id(watermonth).state / id(waterlastmonth).state * 100.00 );
      }else{
        return 0.00;
      }

  # service call delay (updated by id: "waterdisplay")
  - platform: template
    name: ${friendly_name} Daten Intervall
    id: watermeter_read_timeout
    icon: mdi:clock-start
    accuracy_decimals: 2
    unit_of_measurement: "sec"
    state_class: "measurement"
    entity_category: "diagnostic"
    web_server_sorting_weight: 17

  # get the wifi signal from the esp device
  - platform: wifi_signal
    id: wifisignal
    name: ${friendly_name} WiFi Signal
    icon: mdi:wifi-strength-1
    update_interval: 60s
    entity_category: diagnostic
    disabled_by_default: true
    unit_of_measurement: dBm
    accuracy_decimals: 0
    device_class: signal_strength
    state_class: measurement
    web_server_sorting_weight: 29

  # calulcate the wifi signal quality
  - platform: copy # wifi signal in %
    source_id: wifisignal
    id: sensor_wifi_signal_percentage
    name: ${friendly_name} WiFi Qualität
    icon: mdi:wifi-strength-1
    unit_of_measurement: "%"
    state_class: "measurement"
    device_class: ""
    entity_category: diagnostic
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    accuracy_decimals: 2
    web_server_sorting_weight: 35

  # device internal temperature (only webview)
  - platform: internal_temperature
    name: ${friendly_name} Temperatur
    id: device_internal_temperature
    icon: mdi:thermometer-lines
    state_class: "measurement"
    update_interval: 60s
    entity_category: "diagnostic"
    unit_of_measurement: °C
    disabled_by_default: true
    web_server_sorting_weight: 38

  # Uptime device in hours
  - platform: uptime
    name: "${friendly_name} Online seit"
    id: uptime_human
    icon: mdi:clock-start
    filters:
      - filter_out: nan
      - lambda: return x / 3600;
    unit_of_measurement: "h"
    entity_category: "diagnostic"
    state_class: "measurement"
    accuracy_decimals: 2
    web_server_sorting_weight: 16

  # device boot counter by device boot
  - platform: template
    name: ${friendly_name} Anzahl Neustarts
    id: bootcounter
    icon: mdi:counter
    accuracy_decimals: 0
    state_class: "measurement"
    entity_category: "diagnostic"
    lambda: return (id(boot_counter));
    web_server_sorting_weight: 15

## ---------------------------------------------------
## TEXT SENSOR
## ---------------------------------------------------
text_sensor:

  # watermeter status message (updated by script: set_status_message)
  - platform: template
    name: "${friendly_name} Status Info"
    id: watermeter_status_message
    icon: mdi:bell
    entity_category: "diagnostic"
    web_server_sorting_weight: 20

  # watermeter alarm message (updated by id: current_alarms)
  - platform: template
    name: "${friendly_name} Alarm"
    id: watermeter_alarm_message
    icon: mdi:alarm-light
    entity_category: "diagnostic"
    web_server_sorting_weight: 26

  # watermeter previous alarm message (updated by id: current_prev_alarms)
  - platform: template
    name: "${friendly_name} Alarm voriger"
    id: watermeter_alarm_perv_message
    icon: mdi:alarm-light
    entity_category: "diagnostic"
    web_server_sorting_weight: 28

  # watermeter alarm timestamp (updated by id: current_alarms)
  - platform: template
    name: "${friendly_name} Alarm Zeit"
    id: watermeter_alarm_timestamp
    icon: mdi:alarm-light
    entity_category: "diagnostic"
    web_server_sorting_weight: 24

  # optional device version (only for webserver)
  - platform: version
    name: "${friendly_name} ESPHome Version"
    icon: mdi:information-box-outline
    id: appver
    entity_category: "diagnostic"
    hide_timestamp: true
    disabled_by_default: true
    web_server_sorting_weight: 39

  # Last boot timestamp (updated by device boot)
  - platform: template
    name: "${friendly_name} Last Boot"
    disabled_by_default: true
    id: device_lastBoot_time
    icon: mdi:clock-start
    entity_category: "diagnostic"
    web_server_sorting_weight: 37

  # waterdisplay timestamp last update (updated by id: "waterdisplay")
  - platform: template
    name: "${friendly_name} Daten vom"
    id: watermeter_lastupdate
    icon: mdi:clock-start
    web_server_sorting_weight: 11

  # optional device timestamp (only for webserver)
  - platform: template
    id: systime
    name: "${friendly_name} Uhrzeit"
    disabled_by_default: true
    entity_category: "diagnostic"
    icon: mdi:clock-start
    lambda: return id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z");
    web_server_sorting_weight: 36

  # Wifi Info (parts only on webserver)
  # https://esphome.io/components/text_sensor/wifi_info.html
  - platform: wifi_info

    # get the current ssid from the wifi card
    ssid:
      name: ${friendly_name} WIFI SSID
      id: wlan_ssid
      icon: mdi:wifi-settings
      entity_category: "diagnostic"
      web_server_sorting_weight: 30

    # get the current bssid from the wifi card
    bssid:
      name: ${friendly_name} WIFI BSSID
      icon: mdi:wifi-star
      disabled_by_default: true
      entity_category: "diagnostic"
      web_server_sorting_weight: 31

    # get the current used ip address from the wifi card
    ip_address:
      name: ${friendly_name} WIFI IP Address
      icon: mdi:ip
      disabled_by_default: true
      entity_category: "diagnostic"
      web_server_sorting_weight: 34

    # get the current mac address from the wifi card
    mac_address:
      name: ${friendly_name} WIFI MAC-Addresse
      icon: mdi:fingerprint
      entity_category: "diagnostic"
      disabled_by_default: true
      web_server_sorting_weight: 34

    # get the used dns server from the wifi card
    dns_address:
      name: ${friendly_name} WIFI DNS Address
      icon: mdi:dns
      disabled_by_default: true
      entity_category: "diagnostic"
      web_server_sorting_weight: 32

  # simple rest get message for all watermeter data
  # (disable this if you do not need rest service)
  # you can get the sensor data with:
  #   curl -i http://water-meter-esp.local/text_sensor/watermeterdata
  - platform: template
    id: watermeterdata
    internal: true
    disabled_by_default: true
    lambda: |-
      char buf[128];
      sprintf(buf, "%.3f|%.3f|%.3f|%.3f|%.3f|%.3f|%.3f|%.3f|%.3f|%s",
             id(waterdisplay).state,
             id(current_value),
             id(hour_value),
             id(daily_value),
             id(yesterday_value),
             id(week_value),
             id(watermonth).state,
             id(lastmonth_value),
             id(year_value),
             id(systime).state.c_str()
             );
      std::string s = buf;
      return s;
# e.o.f configuration esp32
WulleWulleWapWap commented 2 weeks ago

i did, same log:

[15:33:33][V][rxLoop:167]: Have 45 bytes from CC1101 Rx, RSSI: -22 dBm LQI: 128
[15:33:33][D][mbus:034]: Processing T1 A frame
[15:33:33][V][mbus:045]: Frame: 36571C99934D4EC5932D6B1358E39C2ECC9398D4CD34B59634B64D58D7199968E5A658F26B1B31C99A5396969A (45) [RAW]
[15:33:33][V][mbus:052]: Frame: 1944A51178073087022438E7A171130013510145A0B9F9BE6D8DE5F79F66 (30) [with CRC]
[15:33:33][V][mbus:095]: Validating CRC for Block1
[15:33:33][V][crc:031]:     calculated: 0x38E7, read: 0x38E7
[15:33:33][V][mbus:115]: Validating CRC for Block2
[15:33:33][V][crc:031]:     calculated: 0x9F66, read: 0x9F66
[15:33:33][V][mbus:062]: Frame: 1944A511780730870224A171130013510145A0B9F9BE6D8DE5F7 (26) [without CRC]
[15:33:33][D][wmbus:097]: Using driver 'izar' for ID [0x87300778] RSSI: -22 dBm LQI: 128 Frame: T1 A T: 1944A511780730870224A171130013510145A0B9F9BE6D8DE5F7 (26)
[15:33:33][V][wmbus:121]: Publishing 'current_alarms' = 0.0000
[15:33:33][D][wmbus:925]: Alarm message: \xdc$\xfb?, error code: 0
[15:33:33][V][wmbus:121]: Publishing 'previous_alarms' = 0.0000
[15:33:33][D][wmbus:957]: Alarm message: \xdc$\xfb?, error code: 0
[15:33:33][V][wmbus:121]: Publishing 'remaining_battery_life_y' = 9.5000
[15:33:33][V][wmbus:121]: Publishing 'transmit_period_s' = 8.0000

possible that there is a problem with "total_m3" in wmbusmeter which i can see online, and with "total_water_m3" in you config? I have no clue...

    "media":"water",
    "meter":"izar",
    "name":"",
    "id":"24028730",
    "last_month_total_m3":0,
    "remaining_battery_life_y":9.5,
    "total_m3":15.538,
    "transmit_period_s":8,
    "current_alarms":"no_alarm",
    "last_month_measure_date":"2024-12-01",
    "previous_alarms":"no_alarm",
    "timestamp":"2024-10-29T15:51:22Z"
      total_water_m3:
      id: "waterdisplay"
      name: "${friendly_name} Anzeige"
      unit_of_measurement: "m³"
      state_class: total_increasing
      device_class: "water"
      accuracy_decimals: 3
      icon: mdi:counter
      web_server_sorting_weight: 1
zibous commented 2 weeks ago

testcase see: https://github.com/zibous/ha-watermeter/blob/master/esphome/water-meter-testcase.yaml https://github.com/zibous/ha-watermeter/tree/master/esphome/webserver/v4

WulleWulleWapWap commented 2 weeks ago

water-meter-testcase.yaml, same...

[08:30:00][V][rxLoop:167]: Have 45 bytes from CC1101 Rx, RSSI: -22 dBm LQI: 128
[08:30:00][D][mbus:034]: Processing T1 A frame
[08:30:00][V][mbus:045]: Frame: 36571C99934D4EC5932D6B1358E39C2ECC9398D58D34B59634B64D64DB2C674CAC374B19696B349A6A669A5366 (45) [RAW]
[08:30:00][V][mbus:052]: Frame: 1944A51178073087022438E7A1011300135151885CE81C85608CAAFAA91A (30) [with CRC]
[08:30:00][V][mbus:095]: Validating CRC for Block1
[08:30:00][V][crc:031]:     calculated: 0x38E7, read: 0x38E7
[08:30:00][V][mbus:115]: Validating CRC for Block2
[08:30:00][V][crc:031]:     calculated: 0xA91A, read: 0xA91A
[08:30:00][V][mbus:062]: Frame: 1944A511780730870224A1011300135151885CE81C85608CAAFA (26) [without CRC]
[08:30:00][D][wmbus:097]: Using driver 'izar' for ID [0x87300778] RSSI: -22 dBm LQI: 128 Frame: T1 A T: 1944A511780730870224A1011300135151885CE81C85608CAAFA (26)
[08:30:00][V][wmbus:121]: Publishing 'current_alarms' = 0.0000
[08:30:00][D][wmbus:911]: Alarm message: \xdc$\xfb?, error code: 0
[08:30:00][V][wmbus:121]: Publishing 'previous_alarms' = 0.0000
[08:30:00][D][wmbus:942]: Alarm message: \xdc$\xfb?, error code: 0
[08:30:00][V][wmbus:121]: Publishing 'remaining_battery_life_y' = 9.5000
[08:30:00][V][wmbus:121]: Publishing 'transmit_period_s' = 8.0000

Do i need some encryption key which i dont know or have? Or why isn't it decoding only half of the part what i can decode online at wmbusmeter ? i am pretty confused right now...

Edit: i have a working solution found, with new esphome_components, build a minimal yaml

---
## ------------------------------------------------------------------
## TESTCASE FOR WMBUS METER + CC1101 for WATERMETES
##
## This version has no sensors and shows only
## the logs for checking wM-Bus and CC1101.
##
## DO NOT USE THIS CONFIGURATION FOR PRODUCTION
##
## ------------------------------------------------------------------
substitutions:

  # device and application settings
  device_name_short: "water-meter-esp"
  device_description: "Watermeter CC1101 wmbus Test"
  projectname: "CC1101 wmbus Test.Watermeter"
  appversion: "2.0.7"

# logger settings
  log_level: "VERBOSE"  # not that logging need memory, so in production mode use "WARN"
  log_wmbus: "VERBOSE" # Loglevel for wmbus meters component
  log_baudrate: "0" # 0 disable uart logger messages

  # Device configuration (select your device)

  ## ---------------------------------------------------
  ##
  ##               GDO0
  ##                 o
  ##                 7
  ##                 | GD02         ╭-------o 2 (GND)
  ##                 |  6
  ##                 |  o           |
  ##                 |  |           |
  ##        ╭――x――x――o――o――x――x――x――o――╮
  ##        │       D1  D2          -  │
  ##        │                          │
  ##        │       D1MINI WEMOS       │
  ##   ANT  │                          │ USB
  ##        │                          │
  ##        │           D5 D6 D7 D8 +  │
  ##        ╰――x――x――x――o――o――o――o――o――╯
  ##                    |  |  |  |  |
  ##                    |  |  |  |  ╰-----o  1 (+3.3V)
  ##                    |  o  |  o
  ##                    |  5  |  8
  ##                    | MISO| CSN
  ##                    o     o
  ##                    4     3
  ##                   CLK   MOSI
  ##
  ## --------------------------------------------------
  #BOARD: d1_mini
  #CC1101_3: D7 # MOSI
  #CC1101_4: D5 # CLK
  #CC1101_5: D6 # MISO
  #CC1101_6: D2 # GD02
  #CC1101_7: D1 # GDO0
  #CC1101_8: D8 # CSN

## ----------------------------------------------------------------
## HARDWARE: D1 MINI ESP8266 80MHz, 80KB RAM, 4MB Flash
## ----------------------------------------------------------------
#esp8266:
#  board: ${BOARD}
#  restore_from_flash: true

  ## ------------------------------------------------------------------
  ##
  ##                                                               o 1 (3.3V)
  ##                                                               |
  ##   ╭――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――o―╮
  ##   |                                                             |
  ## - | 5v               az-delivery-devkit-v4                      | -- ANT
  ##   |                                                             |
  ##   |                          16 17 5  18 19               23    |
  ##   ╰――x――x――x――x――x――x――x――x――o――x――o――o――o――o――o――o――o――o――o――o―╯
  ##                              |  |  |  |  |                 |   |
  ##                              o  |  |  o  |                 |   ╰-o - 2 (GND)
  ##                              7  o  |  4  o                 o
  ##                            GDO0 6  | CLK 5                 3
  ##                               GD02 o    MISO              M0SI
  ##                                    8
  ##                                   CSN
  ##
  ## ------------------------------------------------------------------
  BOARD: az-delivery-devkit-v4
  CC1101_3: GPIO23  # M0SI
  CC1101_4: GPIO18  # CLK
  CC1101_5: GPIO19  # MISO
  CC1101_6: GPIO17  # GD02
  CC1101_7: GPIO16  # GDO0
  CC1101_8: GPIO05  # CSN

## ----------------------------------------------------------------
## HARDWARE az-delivery-devkit-v4
##          ESP32 240MHz, 520KB RAM, 4MB Flash
## ----------------------------------------------------------------
esp32:
  board: az-delivery-devkit-v4
  framework:
    type: arduino

  ## ------------------------------------------------------------------
  ##
  ##
  ##       GDO0                 MOSI
  ##         7              MISO  3
  ##         o GD02       CLK  5  o  CSN
  ##         |  6           4  o  |  8           ╭-------o 2 (GND)
  ##         |  o           o  |  |  o           |  ╭----o 1 (3.3V)
  ##         |  |           |  |  |  |           |  |
  ##   ╭――x――o――o――x――x――x――o――o――o――o――x――x――x――o――o―╮
  ##   |     D1 D2          D5 D6 D7 D8               |
  ##   |                                              |
  ## - | ANT              NODEMCU V3                  | -- USB
  ##   |                                              |
  ##   |                                              |
  ##   ╰――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x―╯
  ##
  ##
  ##
  ## ------------------------------------------------------------------
  # BOARD: nodemcuv2
  # CC1101_3: D7  # MOSI
  # CC1101_4: D5  # CLK
  # CC1101_5: D6  # MISO
  # CC1101_6: D2  # GD02
  # CC1101_7: D1  # GDO0
  # CC1101_8: D8  # CSN

# ----------------------------------------------------------------
# HARDWARE:  NODEMCU V3 ESP8266 80MHz, 80KB RAM, 4MB Flash
# ----------------------------------------------------------------
# esp8266:
#   board: ${BOARD}
#   restore_from_flash: true

## ----------------------------------------------------------------
## ESPHOME APPLICATION
## ----------------------------------------------------------------
esphome:
  name: ${device_name_short}
  comment: ${device_description}
  project:
    name: ${projectname}
    version: ${appversion}
  build_path: ./build/${device_name_short}
  on_boot:
    priority: -100.00
    then:
      - logger.log:
          level: INFO
          tag: "system"
          format: "BOOTMESSAGE:${device_name_short} API is connected, Device ready!"
  on_shutdown:
    priority: 700
    then:
      - logger.log:
          level: ERROR
          tag: "system"
          format: "BOOTMESSAGE:${device_name_short} is down!"

## ----------------------------------------------------------------
## External components
## ----------------------------------------------------------------
external_components:
  # uses the latest version from SzczepanLeon
  - source: github://SzczepanLeon/esphome-components@main
    refresh: 0s
    components: [wmbus]

## ---------------------------------------------------
## WIFI Settings 3 wifis
## ---------------------------------------------------
wifi:
  id: wifi_d1mini
  networks:
    - ssid: !secret ssid3_name
      password: !secret ssid3_pswd
      priority: 0
    - ssid: !secret ssid1_name
      password: !secret ssid1_pswd
      priority: 1
    - ssid: !secret ssid2_name
      password: !secret ssid2_pswd
      priority: 2
  domain: !secret domain

## ---------------------------------------------------
## Captive portal component
## ---------------------------------------------------
captive_portal:

## ---------------------------------------------------
## LOGGER COMPONENT
## ---------------------------------------------------
logger:
  id: appslogger
  level: ${log_level}
  baud_rate: ${log_baudrate}
  logs:
    wmbus: ${log_wmbus}
    wMBus-lib: ${log_wmbus}

## ---------------------------------------------------
## OTA Updates
## ---------------------------------------------------
ota:
  password: !secret ota_pswd
  platform: esphome
  on_error:
    then:
      - logger.log:
          level: INFO
          tag: "system"
          format: "OTA update error %d"
          args: ["x"]

## ---------------------------------------------------
## LOCAL WEBSERVER, local settings - no internet
## ---------------------------------------------------
web_server:
  port: 80
  version: 2
  local: true

## ---------------------------------------------------
## SNTP Time server
## ---------------------------------------------------
time:
  - platform: sntp
    id: time_sntp
    timezone: Europe/Berlin
    servers:
      - 0.at.pool.ntp.org
      - 0.pool.ntp.org
      - 1.pool.ntp.org

## ---------------------------------------------------
## CC11001 WMBUS TO DEVICE (selected board)
## ---------------------------------------------------
wmbus:
  mosi_pin: ${CC1101_3}  # MOSI Attached to Hardware SPI controller MOSI SPI Interface
  miso_pin: ${CC1101_5}  # MISO Attached to Hardware SPI controller MISO SPI Interface
  clk_pin: ${CC1101_4}   # SCK  Attached to Hardware SPI controller CLK
  cs_pin: ${CC1101_8}    # CSN  Attached to Hardware SPI controller
  gdo0_pin: ${CC1101_7}  # GDO0 Clock output. High Impedance !
  gdo2_pin: ${CC1101_6}  # GDO2 status signals. High Impedance !

  # Shows telegrams from all watermeters in log.
  #log_unknown: True

  all_drivers: true
  log_all: true

sensor:
  - platform: wmbus
    meter_id: 0x24028730
    type: izar
    key: ""
    sensors:
      - name: "my hot water RSSi"
        field: "rssi"
        accuracy_decimals: 0
        unit_of_measurement: "dBm"
        device_class: "signal_strength"
        state_class: "measurement"
        entity_category: "diagnostic"
      - name: "my hot water"
        field: "total"
        accuracy_decimals: 3
        unit_of_measurement: "m³"
        device_class: "water"
        state_class: "total_increasing"
        icon: "mdi:water"

and the log:

17:31:37    [V] [sensor:043]    

'my hot water': Received new state 15.766000

17:31:37    [D] [sensor:094]    

'my hot water': Sending state 15.76600 m³ with 3 decimals of accuracy

17:31:37    [V] [json:038]  

Attempting to allocate 512 bytes for JSON serialization

17:31:37    [V] [json:058]  

Size after shrink 80 bytes

17:31:45    [V] [rxLoop:167]    

Don't know why its not working with the old version, but with this one it looks good, now have to rebuild more of your work, to test it with HA.

EDIT EDIT: i forgot to mention, that in the old version my watermeter ID from the log was: 0x87300778 and with the new version from leon its 0x24028730 (same like on the sticker from the wm), confusing..

zibous commented 2 weeks ago

Don't know why its not working with the old version, but with this one it looks good, now have to rebuild more of your work, to test it with HA.

Yes, i think this is based on the changes for the Szczepan Leon component v4. Maybe the version 3.0 do not work anymore with the wmbus driver.

WulleWulleWapWap commented 2 weeks ago

so i got it working, but i cant manage to get the alarm working, always the error with "unit_of_measurement required" but, text dont have an unit, you got some idea for a workaround ?

Here is my working version for 4.0 with ESP32 dev4 and IZAR R4

#---
## ------------------------------------------------------------------
## TESTCASE FOR WMBUS METER + CC1101 for WATERMETES
##
## This version has no sensors and shows only
## the logs for checking wM-Bus and CC1101.
##
## DO NOT USE THIS CONFIGURATION FOR PRODUCTION
##
## ------------------------------------------------------------------
substitutions:

  # device and application settings
  device_name_short: "water-meter-esp"
  device_description: "Watermeter CC1101 wmbus Test"
  projectname: "CC1101 wmbus Test.Watermeter"
  friendly_name: "Watermeter" # device name
  appversion: "2.0.7"

# logger settings
  log_level: "VERBOSE"  # not that logging need memory, so in production mode use "WARN"
  log_wmbus: "VERBOSE" # Loglevel for wmbus meters component
  log_baudrate: "0" # 0 disable uart logger messages

## data service (optional, default: False)
## use only if you have a service host present
  service_enabled: "false"
  service_url: !secret service_host
  service: "izar.watermeter"

  # Device configuration (select your device)

  ## ---------------------------------------------------
  ##
  ##               GDO0
  ##                 o
  ##                 7
  ##                 | GD02         ╭-------o 2 (GND)
  ##                 |  6
  ##                 |  o           |
  ##                 |  |           |
  ##        ╭――x――x――o――o――x――x――x――o――╮
  ##        │       D1  D2          -  │
  ##        │                          │
  ##        │       D1MINI WEMOS       │
  ##   ANT  │                          │ USB
  ##        │                          │
  ##        │           D5 D6 D7 D8 +  │
  ##        ╰――x――x――x――o――o――o――o――o――╯
  ##                    |  |  |  |  |
  ##                    |  |  |  |  ╰-----o  1 (+3.3V)
  ##                    |  o  |  o
  ##                    |  5  |  8
  ##                    | MISO| CSN
  ##                    o     o
  ##                    4     3
  ##                   CLK   MOSI
  ##
  ## --------------------------------------------------
  #BOARD: d1_mini
  #CC1101_3: D7 # MOSI
  #CC1101_4: D5 # CLK
  #CC1101_5: D6 # MISO
  #CC1101_6: D2 # GD02
  #CC1101_7: D1 # GDO0
  #CC1101_8: D8 # CSN

## ----------------------------------------------------------------
## HARDWARE: D1 MINI ESP8266 80MHz, 80KB RAM, 4MB Flash
## ----------------------------------------------------------------
#esp8266:
#  board: ${BOARD}
#  restore_from_flash: true

  ## ------------------------------------------------------------------
  ##
  ##                                                               o 1 (3.3V)
  ##                                                               |
  ##   ╭――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――x――o―╮
  ##   |                                                             |
  ## - | 5v               az-delivery-devkit-v4                      | -- ANT
  ##   |                                                             |
  ##   |                          16 17 5  18 19               23    |
  ##   ╰――x――x――x――x――x――x――x――x――o――x――o――o――o――o――o――o――o――o――o――o―╯
  ##                              |  |  |  |  |                 |   |
  ##                              o  |  |  o  |                 |   ╰-o - 2 (GND)
  ##                              7  o  |  4  o                 o
  ##                            GDO0 6  | CLK 5                 3
  ##                               GD02 o    MISO              M0SI
  ##                                    8
  ##                                   CSN
  ##
  ## ------------------------------------------------------------------
  BOARD: az-delivery-devkit-v4
  CC1101_3: GPIO23  # M0SI
  CC1101_4: GPIO18  # CLK
  CC1101_5: GPIO19  # MISO
  CC1101_6: GPIO17  # GD02
  CC1101_7: GPIO16  # GDO0
  CC1101_8: GPIO05  # CSN

## ----------------------------------------------------------------
## HARDWARE az-delivery-devkit-v4
##          ESP32 240MHz, 520KB RAM, 4MB Flash
## ----------------------------------------------------------------
esp32:
  board: az-delivery-devkit-v4
  framework:
    type: arduino

# Customize the frequency in which data is flushed to the flash.
preferences:
  flash_write_interval: 10min

## ----------------------------------------------------------------
## ESPHOME APPLICATION
## ----------------------------------------------------------------
esphome:
  name: ${device_name_short}
  comment: ${device_description}
  project:
    name: ${projectname}
    version: ${appversion}
  build_path: ./build/${device_name_short}
  on_boot:
    priority: -100.00
    then:
      - globals.set:
          id: boot_counter
          value: !lambda "return id(boot_counter)+=1;"
      - globals.set:
          id: send_millisecond
          value: !lambda "return millis();"
      - logger.log:
          level: WARN
          tag: "system"
          format: "BOOTMESSAGE:${device_name_short} API is connected, Device ready!"
  on_shutdown:
    priority: 700
    then:
      - logger.log:
          level: ERROR
          tag: "system"
          format: "BOOTMESSAGE:${device_name_short} is down!"

## ----------------------------------------------------------------
## External components
## ----------------------------------------------------------------
external_components:
  # uses the latest version from SzczepanLeon
  - source: github://SzczepanLeon/esphome-components@main
    refresh: 0s
    components: [wmbus]

## ---------------------------------------------------
## WIFI Settings 3 wifis
## ---------------------------------------------------
wifi:
  id: wifi_d1mini
  networks:
    - ssid: !secret ssid3_name
      password: !secret ssid3_pswd
      priority: 0
    - ssid: !secret ssid1_name
      password: !secret ssid1_pswd
      priority: 1
    - ssid: !secret ssid2_name
      password: !secret ssid2_pswd
      priority: 2
  domain: !secret domain

## ---------------------------------------------------
## Captive portal component
## ---------------------------------------------------
captive_portal:

## ---------------------------------------------------
## LOGGER COMPONENT
## ---------------------------------------------------
logger:
  id: appslogger
  level: ${log_level}
  baud_rate: ${log_baudrate}
  logs:
    wmbus: ${log_wmbus}
    wMBus-lib: ${log_wmbus}
    sensor: WARN
    sensor.filter: WARN
    text_sensor: WARN
    api.service: ERROR
    json: ERROR
    mqtt: WARN
    scheduler: ERROR
    internal_temperature: ERROR
    wifi: WARN
    component: ERROR
    api: WARN

## ----------------------------------------------------------------
## GLOBALS VARIABLES
## ----------------------------------------------------------------

globals:

  - id: boot_counter
    type: int
    restore_value: yes
    initial_value: "0"

  - id: last_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: current_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: hour_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: daily_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: yesterday_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: week_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: lastmonth_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: year_value
    type: float
    restore_value: yes
    initial_value: "0.00"

  - id: send_millisecond
    type: int
    restore_value: no
    initial_value: '0'

  - id: cc1101_state
    type: int
    restore_value: no
    initial_value: '0'

  - id: alarm_error_text
    type: std::vector<std::string>
    restore_value: no
    # initial_value: '{"no error", "general_alarm","leakage","meter_blocked","back_flow","underflow","overflow","submarine","sensor_fraud","mechanical_fraud"}'
    initial_value: '{"Keiner", "Fehler","Zähler undicht","Zähler blockiert","Wasser Rückfluss","Wasser Unterlauf","Wasser Überlauf","Überschwemung","Sensor Fehler", "Mechanischer Fehler"}'

  - id: cc1101_state_message
    type: std::vector<std::string>
    restore_value: no
    initial_value: '{"Init", "Warte auf Daten", "Daten empfangem", "Ready", "Error"}'

## ---------------------------------------------------
## OTA Updates
## ---------------------------------------------------
ota:
  password: !secret ota_pswd
  platform: esphome
  on_begin:
    then:
      - logger.log:
          format: "OTA Start"
          tag: "OTA"
          level: WARN
  on_progress:
    then:
      - logger.log:
          level: WARN
          tag: "OTA"
          format: "OTA progress %0.1f%%"
          args: ["x"]
  on_end:
    then:
      - logger.log:
          format: "OTA End"
          tag: "OTA"
          level: WARN
  on_error:
    then:
      - logger.log:
          format: "OTA update error %d"
          tag: "OTA"
          level: ERROR
          args: ["x"]

## ---------------------------------------------------
## LOCAL WEBSERVER, local settings - no internet
## ---------------------------------------------------
web_server:
 port: 80
 version: 3
 local: False
 js_url: !secret webserver_jsurl

## ---------------------------------------------------
## COMPONENT HTTP (optional)
## Prepare for sending HTTP requests
## ---------------------------------------------------
http_request:
  verify_ssl: false
  id: http_request_data
  useragent: ${service}
  timeout: 10s 

## ---------------------------------------------------
## COMPONENT Home Assistant API
## Homeassistant service call (all values in liter):
## ---------------------------------------------------
## service: esphome.water_meter_esp_set_watermeter_esp_data
## data:
##   water_val_hour: 0.00
##   water_val_day: 167.00
##   water_val_yesterday: 240.35
##   water_val_week: 901.00
##   water_val_year: 33143.00
##   water_val_lastmonth: 7580.25
## ---------------------------------------------------
api:
  id: espapi_wmbus_esp32
  port: 6053
  reboot_timeout: 0s
  # https://esphome.io/components/api.html?highlight=api
  #encryption:
  #  key: "inH49O9jBeK5yTGb1X2g4WV/1aS6YKUpu3Vu277fDgw="
  services:
    - service: set_watermeter_esp_data
      variables:
        water_val_hour: float
        water_val_day: float
        water_val_yesterday: float
        water_val_week: float
        water_val_year: float
        water_val_lastmonth: float
      then:
        - globals.set:
            id: hour_value
            value: !lambda |-
              if((water_val_hour) and (water_val_hour)>0.001){
                ESP_LOGD("system", "Set hourly value to: %f", water_val_hour);
                return (water_val_hour);
              }else{
                ESP_LOGD("system", "Skip setting hourly value");
                return id(hour_value);
              };
              id(waterhour).publish_state(id(hour_value));

        - globals.set:
            id: daily_value
            value: !lambda |-
              if((water_val_day) and (water_val_day)>0.001){
                ESP_LOGD("system", "Set daily value to: %f", water_val_day);
                return (water_val_day);
              }else{
                ESP_LOGD("system", "Skip setting hourly value");
                return id(hour_value);
              };
              id(waterday).publish_state(id(daily_value));

        - globals.set:
            id: yesterday_value
            value: !lambda |-
              if((water_val_yesterday) and (water_val_yesterday)>0.001){
                ESP_LOGD("system", "Set yesterday value to: %f", water_val_yesterday);
                return (water_val_yesterday);
              }else{
                ESP_LOGD("system", "Skip setting yesterday value");
                return id(yesterday_value);
              };
              id(wateryesterday).publish_state(id(hour_value));

        - globals.set:
            id: week_value
            value: !lambda |-
              if((water_val_week) and (water_val_week)>0.001){
                ESP_LOGD("system", "Set weekly value to: %f", water_val_week);
                return (water_val_week);
              }else{
                ESP_LOGD("system", "Skip setting weekly value");
                return id(week_value);
              };
              id(waterweek).publish_state(id(week_value));

        - globals.set:
            id: lastmonth_value
            value: !lambda |-
              if((water_val_lastmonth) and (water_val_lastmonth)>0.001){
                ESP_LOGD("system", "Set last month value to: %f", water_val_lastmonth);
                return (water_val_lastmonth);
              }else{
                ESP_LOGD("system", "Skip setting last month value");
                return id(lastmonth_value);
              };
              id(waterlastmonth).publish_state(id(lastmonth_value));

        - globals.set:
            id: year_value
            value: !lambda |-
              if((water_val_year) and (water_val_year)>0.001){
                ESP_LOGD("system", "Set last yearly value to: %f", water_val_year);
                return (water_val_year);
              }else{
                ESP_LOGD("system", "Skip setting last yearly value");
                return id(year_value);
              };
              id(wateryear).publish_state(id(year_value));

        - logger.log:
            tag: "system"
            format: "All new Values set: hour: %.3f, day: %.3f, week: %.3f, last month: %.3f, year: %.3f"
            level: INFO
            args:
              [
                "id(hour_value)",
                "id(daily_value)",
                "id(week_value)",
                "id(lastmonth_value)",
                "id(year_value)",
              ]

## ---------------------------------------------------
## COMPONENT SCRIPTS
## ---------------------------------------------------
script:

  # id(set_status_message).execute();
  - id: set_status_message
    then:
        - lambda: |-
            int msgcode = int(id(cc1101_state));
            std::string message = id(cc1101_state_message)[msgcode];
            ESP_LOGD("wmbus", "cc1101 state message: %s, error code: %d", message.c_str(), msgcode);
            id(watermeter_status_message).publish_state(message);

  # id(post_device_state).execute();
  - id: post_device_state
    then:
      - if:
          condition:
            lambda: return "${service_enabled} =='true'";
          then:
            - logger.log:
                tag: "system"
                level: INFO
                format: "Post new data to the ${service_url}${device_name_short}, service enabled: ${service_enabled}"
            - http_request.post:
                url: "http://${device_name_short}"
                headers:
                  Content-Type: application/json
                json: |-
                  root["device"] = "${device_name_short}";
                  root["waterdisplay"] = id(waterdisplay).state;
                  root["current"] = id(id(watercurrent)).state;
                  root["hour"] = id(waterhour).state;
                  root["day"] = id(waterday).state;
                  root["yesterday"] = id(wateryesterday).state;
                  root["week"] = id(waterweek).state;
                  root["month"] = id(watermonth).state;
                  root["lastmonth"] = id(waterhour).state;
                  root["year"] = id(wateryear).state;
                  root["bootcounter"] = id(bootcounter).state;
                  root["version"] = "${device_name_short} ${appversion}";
                  root["time"] = id(time_sntp).now().strftime("%Y-%m-%d %H:%M:%S");
                on_response:
                  then:
                    - lambda: |-
                        if (response->status_code == 200) {
                           ESP_LOGI ("system", "HTTP POST o.k");
                        } else {
                            ESP_LOGI ("system", "HTTP POST failed");
                        }

## ---------------------------------------------------
## SNTP Time server
## ---------------------------------------------------
time:
  - platform: sntp
    id: time_sntp
    timezone: Europe/Berlin
    servers:
      - !secret local_sntp
      - 0.at.pool.ntp.org
      - 0.pool.ntp.org

#api:
#  id: espapi_wmbus_esp32
#  port: 6053
#  reboot_timeout: 0s

## ---------------------------------------------------
## SWITCHES
## ---------------------------------------------------
switch:
#   # reset boot counter value
#   - platform: template
#     name: "${friendly_name} Boot Counter Reset"
#     icon: mdi:lock-reset
#     turn_on_action:
#       then:
#         - lambda: |-
#             id(boot_counter) = 0;
#             id(bootcounter).publish_state(id(boot_counter));
#         - logger.log:
#             level: WARN
#             tag: "system"
#             format: "${device_name_short} reset boot counter o.k!"
#         - component.update: bootcounter

#   # reset all global vars
#   - platform: template
#     name: "Wasseruhr Reset values"
#     icon: mdi:lock-reset
#     turn_on_action:
#       then:
#         - lambda: |-
#             id(last_value) = 0.00;
#             id(boot_counter) = 0;
#             id(bootcounter).publish_state(id(boot_counter));
#             id(current_value) = 0.00;
#             id(watercurrent).publish_state(id(current_value));
#             id(hour_value) = 0.00;
#             id(waterhour).publish_state(id(hour_value));
#             id(daily_value) = 0.00;
#             id(waterday).publish_state(id(daily_value));
#             id(yesterday_value) = 0.00;
#             id(wateryesterday).publish_state(id(yesterday_value));
#             id(week_value) = 0.00;
#             id(waterweek).publish_state(id(week_value));
#             id(lastmonth_value) = 0.00;
#             id(waterlastmonth).publish_state(id(lastmonth_value));
#             id(year_value) = 0.00;
#             id(wateryear).publish_state(id(year_value));
#         - logger.log:
#             level: INFO
#             tag: "system"
#             format: "all values reset!"

   # restarts the device
   - platform: restart
     name: "${friendly_name} Restart"
     id: restart_switch
     icon: mdi:restart

## ---------------------------------------------------
## CC11001 WMBUS TO DEVICE (selected board)
## ---------------------------------------------------
wmbus:
  mosi_pin: ${CC1101_3}  # MOSI Attached to Hardware SPI controller MOSI SPI Interface
  miso_pin: ${CC1101_5}  # MISO Attached to Hardware SPI controller MISO SPI Interface
  clk_pin: ${CC1101_4}   # SCK  Attached to Hardware SPI controller CLK
  cs_pin: ${CC1101_8}    # CSN  Attached to Hardware SPI controller
  gdo0_pin: ${CC1101_7}  # GDO0 Clock output. High Impedance !
  gdo2_pin: ${CC1101_6}  # GDO2 status signals. High Impedance !

  # Shows telegrams from all watermeters in log.
  #log_unknown: True

  all_drivers: false
  log_all: false

#sensor:
#  - platform: wmbus
#    meter_id: 0x00148686
#    type: apator162
#    key: "00000000000000000000000000000000"
#    sensors:
#      - name: "my hot water RSSi"
#        field: "rssi"
#        accuracy_decimals: 0
#        unit_of_measurement: "dBm"
#        device_class: "signal_strength"
#        state_class: "measurement"
#        entity_category: "diagnostic"

sensor:
  - platform: wmbus
    meter_id: 0x24028730
    type: izar
    key: ""
    sensors:
      - name: "Wasserzaehler"
        id: "waterdisplay"
        field: "total"
        accuracy_decimals: 3
        unit_of_measurement: "m³"
        device_class: "water"
        state_class: "total_increasing"
        icon: "mdi:water"
        on_value:
         then:
          - lambda: |-
              if ((id(last_value) > 0.00) and (id(waterdisplay).state)>(id(last_value)) ) {
                id(cc1101_state) = 2;
                ESP_LOGI("wmbus", "Water Display value: %.3f, last value: %.3f", id(waterdisplay).state, id(last_value));
                id(current_value) = float(id(waterdisplay).state-id(last_value)) * 1000.00;
                id(watercurrent).publish_state(id(current_value));
                id(hour_value)+=id(current_value);
                id(waterhour).publish_state(id(hour_value));
                id(daily_value)+=id(current_value);
                id(waterday).publish_state(id(daily_value));
                id(week_value)+=id(current_value);
                id(waterweek).publish_state(id(week_value));
                id(year_value)+=id(current_value);
                id(wateryear).publish_state(id(year_value));
                ESP_LOGD("wmbus", "Set current value to %.3f litre and publish the data", id(current_value));
                if ( ${service_enabled} == true){
                  id(post_device_state).execute();
                }else{
                  ESP_LOGD("wmbus", "Data Service to host disabled");
                }
              }else{
                id(current_value) = 0.00;
                id(cc1101_state) = 1;
                id(watercurrent).publish_state(id(current_value));
                ESP_LOGI("wmbus", "Reset current value to: %.3f, Waterdisplay value: %.3f, last value: %.3f", id(current_value), id(waterdisplay).state, id(last_value));
              }
              id(last_value)=id(waterdisplay).state;
      - name: "Wasserzaehler RSSi"
        field: "rssi"
        accuracy_decimals: 0
        unit_of_measurement: "dBm"
        device_class: "signal_strength"
        state_class: "measurement"
        entity_category: "diagnostic"
      - name: "Wasseruhr Batterielebensdauer"
        field: "remaining_battery_life"
        accuracy_decimals: 2
        unit_of_measurement: "y"
        state_class: "measurement"
        entity_category: "diagnostic"
        icon: "mdi:battery"
      - name: "Wasseruhr Update Inverall"
        field: "transmit_period"
        accuracy_decimals: 2
        unit_of_measurement: "s"
        state_class: "measurement"
        entity_category: "diagnostic"
        icon: "mdi:timelapse"
      - name: "Wasseruhr Alarm Code"
        id: "watermeter_current_alarms"
        field: "current_alarms"
        unit_of_measurement: "alarms"
        entity_category: "diagnostic"
        icon: mdi:message-alert-outline
        on_value:
         then:
          - lambda: |-
              int error_code = int(x);
              std::string message = "";
              if(error_code==0){
                  message = id(alarm_error_text)[error_code];
                  id(watermeter_alarm_message).publish_state(message);
                  ESP_LOGD("wmbus", "Alarm message: %s, error code: %d", message, error_code);
              }else{
                for (int i = 1; i < 10; ++i) {
                  if (error_code & (1 << i)) {
                    if (!message.empty()) {
                      message += ", ";
                    }
                    message += id(alarm_error_text)[i];
                  }
                }
                id(watermeter_alarm_message).publish_state(message);
                ESP_LOGW("wmbus", "WARNING Alarm message: %s, error code: %d", message.c_str(), error_code);
                id(watermeter_alarm_timestamp).publish_state(id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z").c_str());
              }
      - name: "Wasseruhr Alarm Code voriger"
        id: "watermeter_previous_alarms"
        field: "previous_alarms"
        entity_category: "diagnostic"
        unit_of_measurement: "alarms"
        icon: "mdi:message-alert"
        on_value:
         then:
           - lambda: |-
               int error_code = int(x);
               std::string message = "";
               if(error_code==0){
                   message = id(alarm_error_text)[error_code];
                   id(watermeter_alarm_message).publish_state(message);
                   ESP_LOGD("wmbus", "Alarm message: %s, error code: %d", message, error_code);
               }else{
                 for (int i = 1; i < 10; ++i) {
                   if (error_code & (1 << i)) {
                     if (!message.empty()) {
                       message += ", ";
                     }
                     message += id(alarm_error_text)[i];
                   }
                 }
                 ESP_LOGW("wmbus", "WARNING Alarm message: %s, error code: %d", message.c_str(), error_code);
                 id(watermeter_alarm_timestamp).publish_state(id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z").c_str());
               }
               id(watermeter_alarm_perv_message).publish_state(message);
               if(id(watermeter_alarm_timestamp).has_state() == false) {
                 id(watermeter_alarm_timestamp).publish_state("--");
               }
      - name: "Wasser Monat"
        id: "watermonth"
        field: "last_month_total"
        accuracy_decimals: 3
        unit_of_measurement: "m³"
        icon: mdi:water-outline
        state_class: total_increasing
        device_class: "water"

  # water current (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Aktuell
    id: "watercurrent"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-well
    state_class: "measurement"
    device_class: "water"
    lambda: return (id(current_value));

  # water current hour (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Stunde
    id: "waterhour"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-well-outline
    state_class: total_increasing
    device_class: "water"
    lambda: return (id(hour_value));

  # water today (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Tag
    id: "waterday"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-well-outline
    device_class: "water"
    state_class: total_increasing
    lambda: return (id(daily_value));

  # water yesterday (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Gestern
    id: "wateryesterday"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-well-outline
    device_class: "water"
    state_class: total_increasing
    lambda: return (id(yesterday_value));

  # water current week (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Woche
    id: "waterweek"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    icon: mdi:water-well-outline
    device_class: "water"
    state_class: total_increasing
    lambda: return (id(week_value));

  # water last month (updated by id: "waterdisplay")
  - platform: template
    name: Wasser letzer Monat
    id: "waterlastmonth"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: total_increasing
    device_class: "water"
    lambda: return (id(lastmonth_value));

  # water current year (updated by id: "waterdisplay")
  - platform: template
    name: Wasser Jahr
    id: "wateryear"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: total_increasing
    device_class: "water"
    lambda: return (id(year_value));

  # service call delay (updated by id: "waterdisplay")
  - platform: template
    name: Wasseruhr Daten Intervall
    id: watermeter_read_timeout
    icon: mdi:clock-start
    accuracy_decimals: 2
    unit_of_measurement: "sec"
    state_class: "measurement"
    entity_category: "diagnostic"

  # Wifi quality RSSI (%)
  - platform: wifi_signal
    name: "${friendly_name} WLAN Signal"
    id: wifi_signal_db
    update_interval: 60s
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    entity_category: "diagnostic"
    unit_of_measurement: "%"

  # device internal temperature (only webview)
  - platform: internal_temperature
    name: Device Internal Temperature
    id: device_internal_temperature
    icon: mdi:thermometer-lines
    state_class: "measurement"
    update_interval: 60s
    entity_category: "diagnostic"
    disabled_by_default: true

  # the current size of free heap memory.
  - platform: template
    name: ${friendly_name} Free Heap Min
    id: sysfreemapmin
    icon: mdi:counter
    lambda: return {static_cast<float>(esp_get_minimum_free_heap_size())};
    unit_of_measurement: B
    update_interval: 2s
    entity_category: "diagnostic"

  # Minimum free heap ever available
  - platform: template
    name: ${friendly_name} Free Heap
    id: sysfreeheap
    icon: mdi:counter
    lambda: return {static_cast<float>(esp_get_free_heap_size())};
    unit_of_measurement: B
    update_interval: 2s
    entity_category: "diagnostic"

  # Free memory
  - platform: template
    name: "${friendly_name} - Free Memory"
    # lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL) / 1024;
    lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
    unit_of_measurement: "B"
    state_class: measurement

  # Uptime device in hours
  - platform: uptime
    name: "${friendly_name} Online seit"
    id: uptime_human
    icon: mdi:clock-start
    filters:
      - lambda: return x / 3600;
    unit_of_measurement: "h"
    entity_category: "diagnostic"
    state_class: "measurement"
    accuracy_decimals: 2

  # device boot counter by device boot
  - platform: template
    name: "${friendly_name} Boot counter"
    id: bootcounter
    icon: mdi:counter
    accuracy_decimals: 0
    state_class: "measurement"
    entity_category: "diagnostic"
    lambda: return (id(boot_counter));

## ---------------------------------------------------
## TEXT SENSOR
## ---------------------------------------------------
text_sensor:

  # watermeter status message (updated by script: set_status_message)
  - platform: template
    name: "Wasseruhr Status Info"
    id: watermeter_status_message
    icon: mdi:bell
    entity_category: "diagnostic"

  # watermeter alarm message (updated by id: current_alarms)
  - platform: template
    name: "Wasseruhr Alarm"
    id: watermeter_alarm_message
    icon: mdi:alarm-light
    entity_category: "diagnostic"

  # watermeter previous alarm message (updated by id: current_prev_alarms)
  - platform: template
    name: "Wasseruhr Alarm voriger"
    id: watermeter_alarm_perv_message
    icon: mdi:alarm-light
    entity_category: "diagnostic"

  # watermeter alarm timestamp (updated by id: current_alarms)
  - platform: template
    name: "Wasseruhr Alarm Zeit"
    id: watermeter_alarm_timestamp
    icon: mdi:alarm-light
    entity_category: "diagnostic"

  # optional device version (only for webserver)
  - platform: version
    name: "${friendly_name} ESPHome Version"
    icon: mdi:application-cog-outline
    id: appver
    hide_timestamp: true
    disabled_by_default: true

  # Last boot timestamp (updated by device boot)
  - platform: template
    name: "Device Last Boot"
    disabled_by_default: true
    id: device_lastBoot_time
    icon: mdi:clock-start

  # optional device timestamp (only for webserver)
  - platform: template
    id: systime
    disabled_by_default: true
    icon: mdi:clock-start
    lambda: return id(time_sntp).now().strftime("%Y-%m-%dT%H:%M:%S %Z");

  # connected to ssid (only for webserver)
  - platform: wifi_info
    ssid:
      name: ${friendly_name} WLAN SSID
      id: wlan_ssid
      disabled_by_default: true
      icon: mdi:wifi-settings
## Nothing follow here, output only on log console
SzczepanLeon commented 2 weeks ago

There is no workaround. Please wait for next version.

WulleWulleWapWap commented 2 weeks ago

Ok ty. at least all other components are working now. :)

issue can be closed.

SzczepanLeon commented 2 weeks ago

Please try this version:

external_components:
  - source: github://SzczepanLeon/esphome-components@text_fields
    refresh: 0d
    components: [ wmbus ]

and in config:

text_sensor:
  - platform: wmbus
    meter_id: 0x12344321
    type: izar
    sensors:
      - name: "Izar current_alarms"
        field: "current_alarms"