Giter Club home page Giter Club logo

Comments (10)

zibous avatar zibous commented on June 15, 2024 1

hi,

Szczepan Leon makes a good job, in Version 2.0 this is allready present.

see: https://github.com/SzczepanLeon/esphome-components/blob/main/components/wmbus/driver_topaseskr.h

QAD - try this

## ------------------------------------------------------------------
## WMBUS METER D1 MINI + CC1101 for Diehl IZAR RC 868 I R4 PL
##
## usage:  1. Using Homassistant API (discovery + devices)
##         2. External custom component from SzczepanLeon
##
## ------------------------------------------------------------------
substitutions:
  device_name_short: "water-meter-izar"
  device_description: "Wasserzähler Wemos D1 Min, CUL - CC1101, IZAR module (Diehl IZAR RC 868 I R4 PL) simple SzczepanLeon"

  update_interval: 60s
  log_level: "VERBOSE" # use VERBOSE mode to find the meterId 0x43430778
  appversion: "1.1.7"

  domain: !secret domain


esphome:
  name: ${device_name_short}
  # HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
  platform: ESP8266
  board: d1_mini
  esp8266_restore_from_flash: true
  arduino_version: recommended
  comment: ${device_description}
  project:
    name: "OE9psj.wmbus-minid2"
    version: ${appversion}
  build_path: ./build/${device_name_short}

  ## ----------------------------------------------------------------
  ## External components for wmbusmeter
  ## ----------------------------------------------------------------
  on_boot:
    # At this priority, pretty much everything should already be initialized.
    priority: -100.0
    then:
      - logger.log:
          level: INFO
          tag: "BOOT"
          format: "BOOTMESSAGE:${device_name_short} API is connected, Device ready!"
      - globals.set:
          id: boot_counter
          value: !lambda "return id(boot_counter)+=1;"

  on_shutdown:
    priority: 600
    then:
      - logger.log:
          level: INFO
          tag: "BOOT"
          format: "BOOTMESSAGE:${device_name_short} is down!"

## ----------------------------------------------------------------
## External components for wmbusmeter
## ----------------------------------------------------------------
external_components:
  # use exterban component 2.0 from
  # https://github.com/SzczepanLeon/esphome-components
  - source: github://SzczepanLeon/esphome-components@main
    refresh: 0d
    components: [ wmbus ]

## ----------------------------------------------------------------
## Global variables
## ----------------------------------------------------------------
globals:
  - id: boot_counter
    type: int
    restore_value: yes
    initial_value: "0"

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

  - id: float_default
    type: float
    restore_value: no
    initial_value: "0.00"

  - id: m3toliter
    type: float
    initial_value: "1000.00"
    restore_value: yes

  - 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: month_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"

## ---------------------------------------------------
## WIFI Settings 3 wifis
## ---------------------------------------------------
wifi:
  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

## ---------------------------------------------------
## The captive portal component in ESPHome is a
## fallback mechanism for when connecting to the
## configured WiFi fails.
## ---------------------------------------------------
captive_portal:

logger:
  id: appslogger
  level: ${log_level}
  baud_rate: 0 #disable logging over uart

## ---------------------------------------------------
## Enable Home Assistant API
## ---------------------------------------------------
## Homeassistant service call:
## service: esphome.water_meter_set_water_val
## data:
##  water_val_hour: 0.03
##  water_val_day: 0.248
##  water_val_yesterday: 0.178
##  water_val_week: 0.248
##  water_val_month: 1.94
##  water_val_year: 14.256
##  water_val_lastmonth: 9.59
## ---------------------------------------------------
api:
  id: espapiwm2_d2
  port: 6053
  reboot_timeout: 0s
  services:
    - service: set_water_val
      variables:
        water_val_hour: float
        water_val_day: float
        water_val_yesterday: float
        water_val_week: float
        water_val_month: 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_LOGI("main", "Set hourly value to: %f", water_val_hour);
                return (water_val_hour);
              }else{
                ESP_LOGI("main", "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_LOGI("main", "Set daily value to: %f", water_val_day);
                return (water_val_day);
              }else{
                ESP_LOGI("main", "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_LOGI("main", "Set yesterday value to: %f", water_val_yesterday);
                return (water_val_yesterday);
              }else{
                ESP_LOGI("main", "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_LOGI("main", "Set weekly value to: %f", water_val_week);
                return (water_val_week);
              }else{
                ESP_LOGI("main", "Skip setting weekly value");
                return id(week_value);
              };
              id(waterweek).publish_state(id(week_value));

        - globals.set:
            id: month_value
            value: !lambda |-
              if((water_val_month) and (water_val_month)>0.001){
                ESP_LOGI("main", "Set last montj value to: %f", water_val_month);
                return (water_val_month);
              }else{
                ESP_LOGI("main", "Skip setting monthly value");
                return id(week_value);
              };
              id(watermonth).publish_state(id(month_value));

        - globals.set:
            id: lastmonth_value
            value: !lambda |-
              if((water_val_lastmonth) and (water_val_lastmonth)>0.001){
                ESP_LOGI("main", "Set last month value to: %f", water_val_lastmonth);
                return (water_val_lastmonth);
              }else{
                ESP_LOGI("main", "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_LOGI("main", "Set last yearly value to: %f", water_val_year);
                return (water_val_year);
              }else{
                ESP_LOGI("main", "Skip setting last yearly value");
                return id(week_value);
              };
              id(wateryear).publish_state(id(year_value));

        - logger.log:
            format: "All new Values set: hour: %.1f, day: %.1f, week: %.1f, month: %.1f, lastmonth: %.1f, year: %.1f"
            args:
              [
                "id(hour_value)",
                "id(daily_value)",
                "id(week_value)",
                "id(month_value)",
                "id(lastmonth_value)",
                "id(year_value)",
              ]

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

## ----------------------------------------------------------------------
## LOCAL WEBSERVER Settings, local settings - no internet
## Include supporting javascript locally allowing it to work
## without internet access.
## ----------------------------------------------------------------------
web_server:
  port: 80
  version: 2
  local: true

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

    on_time_sync:
      then:
        - logger.log: "Synchronized sntp clock"

    # reset hourly value
    on_time:
      - seconds: 0
        minutes: 0
        then:
          - globals.set:
              id: hour_value
              value: "0.00"
          - lambda: id(waterhour).publish_state(id(hour_value));
          - logger.log: 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);
          - lambda: id(wateryesterday).publish_state(id(yesterday_value));
          - lambda: id(daily_value)=0.00;
          - lambda: id(waterday).publish_state(id(daily_value));
          - logger.log: 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: Reset value weekly, starting new week

      # reset monthly value and set last month value
      - seconds: 0
        minutes: 0
        hours: 0
        days_of_month: 1
        then:
          - globals.set:
              id: month_value
              value: "0.00"
          - lambda: id(watermonth).publish_state(id(month_value));
          - lambda: |-
              if(id(waterdisplay).state){
                id(lastmonth_value)=id(waterdisplay).state;
              }
          - logger.log: Reset value monthly, starting new month

      # 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: Reset value yearly, starting new year

## ---------------------------------------------------
## WMBUS DEVICE D1MINI WEMOS
## ---------------------------------------------------
wmbus:
  ## connction to CC1101
  mosi_pin: GPIO13 #D7  MOSI Attached to Hardware SPI controller MOSI SPI Interface
  miso_pin: GPIO12 #D6  MISO Attached to Hardware SPI controller MISO SPI Interface
  clk_pin: GPIO14 #D5  SCK  Attached to Hardware SPI controller CLK
  cs_pin: GPIO15 #D8  CSN  Attached to Hardware SPI controller, Controls Boot Mode; CS SPI Interface 10k Pull-Down, boot fails if pulled high !!!
  gdo0_pin: GPIO04 #D2  High Impedance
  gdo2_pin: GPIO05 #D1  High Impedance

## ---------------------------------------------------
## SWITCHES
## ---------------------------------------------------
switch:
  # reset boot counter value
  - platform: template
    name: Reset Boot Counter
    turn_on_action:
      then:
        - lambda: |-
            id(boot_counter) = id(int_default);
            id(bootcounter).publish_state(id(boot_counter));
        - logger.log:
            level: INFO
            tag: "BOOT"
            format: "${device_name_short} reset boot counter o.k!"

  # reset all global vars
  - platform: template
    name: Reset values
    turn_on_action:
      then:
        - lambda: |-
            id(last_value) = id(float_default);

            id(boot_counter) = id(int_default);
            id(bootcounter).publish_state(id(boot_counter));

            id(current_value) = id(float_default);
            id(watercurrent).publish_state(id(current_value));

            id(hour_value) = id(float_default);
            id(waterhour).publish_state(id(hour_value));

            id(daily_value) = id(float_default);
            id(waterday).publish_state(id(daily_value));

            id(yesterday_value) = id(float_default);
            id(wateryesterday).publish_state(id(yesterday_value));

            id(week_value) = id(float_default);
            id(waterweek).publish_state(id(week_value));

            id(month_value) = id(float_default);
            id(watermonth).publish_state(id(month_value));

            id(lastmonth_value) = id(float_default);
            id(waterlastmonth).publish_state(id(lastmonth_value));

            id(year_value) = id(float_default);
            id(wateryear).publish_state(id(year_value));

        - logger.log: all values reset!

  - platform: restart
    name: "Restart"
    id: restart_switch


## ---------------------------------------------------
## SENSORS
## ---------------------------------------------------
sensor:
  # water display
  - platform: wmbus
    name: "Wasseruhr Anzeige"
    id: "waterdisplay"
    # Meter ID (usually from sticker). Can be specified as decimal or hex.
    # only hex is working for my watermeter !
    # use meter_id: 0  to see all watermeters
    meter_id: 0 ## !secret watermeterId
    type: topaseskr
    lqi:
      name: "My lqi"
     rssi:
      name: "My RSSI"
    total_water_m3:
        unit_of_measurement: "m³"
        state_class: total_increasing
        device_class: "water"
        accuracy_decimals: 3
        on_value:
          then:
            - lambda: |-
                ESP_LOGI("SENSOR", "Water Display value: %f, last value: %f", id(waterdisplay).state, id(last_value));

                if ((id(last_value) > 0.00) and (id(waterdisplay).state)>(id(last_value)) ) {

                  id(current_value) = (id(waterdisplay).state-id(last_value)) * id(m3toliter);
                  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(month_value)+=id(current_value);
                  id(watermonth).publish_state(id(month_value));

                  id(year_value)+=id(current_value);
                  id(wateryear).publish_state(id(year_value));

                  ESP_LOGI("SENSOR", "Set current value to %f litre and publish the data", id(watercurrent));

                }else{

                  id(current_value) = 0.00;
                  id(watercurrent).publish_state(id(current_value));
                  ESP_LOGI("SENSOR", "Reset current value to: %f", id(watercurrent));

                }
                id(last_value)=id(waterdisplay).state;

            - text_sensor.template.publish:
                id: watermeter_lastupdate
                state: !lambda |-
                  char str[20];
                  time_t currTime = id(sntp_time).now().timestamp;
                  strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%S", localtime(&currTime));
                  return (std::string) str;

  # water current
  - platform: template
    name: Wasser Aktuell
    id: "watercurrent"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: "measurement"
    device_class: "water"
    lambda: |-
      return (id(current_value));

  # water current hour
  - platform: template
    name: Wasser Stunde
    id: "waterhour"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: total_increasing
    device_class: "water"
    lambda: |-
      return (id(hour_value));

  # water today
  - platform: template
    name: Wasser Tag
    id: "waterday"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    device_class: "water"
    state_class: total_increasing
    lambda: |-
      return (id(daily_value));

  # water yesterday
  - platform: template
    name: Wasser Gestern
    id: "wateryesterday"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    device_class: "water"
    state_class: total_increasing
    lambda: |-
      return (id(yesterday_value));

  # water current week
  - platform: template
    name: Wasser Woche
    id: "waterweek"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    device_class: "water"
    state_class: total_increasing
    lambda: |-
      return (id(week_value));

  # water current month
  - platform: template
    name: Wasser Monat
    id: "watermonth"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: total_increasing
    device_class: "water"
    lambda: |-
      return (id(month_value));

  # water current year
  - 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));

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

  # device boot counter
  - platform: template
    name: Boot counter
    id: bootcounter
    accuracy_decimals: 0
    entity_category: "diagnostic"
    state_class: "measurement"
    lambda: |-
      return (id(boot_counter));

  # device uptime human reading format
  # only internal used
  - platform: uptime
    name: Uptime
    id: uptime_sensor
    internal: true
    update_interval: ${update_interval}
    unit_of_measurement: seconds
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? String(days) + "d " : "") +
                (hours ? String(hours) + "h " : "") +
                (minutes ? String(minutes) + "m " : "") +
                (String(seconds) + "s")
              ).c_str();

  # Wifi quality RSSI
  - platform: wifi_signal
    name: Wlan Signal
    id: wifi_signal_db
    update_interval: 60s
    internal: true
    entity_category: "diagnostic"

  # Wifi quality RSSI in percentage
  - platform: copy # Reports the WiFi signal strength in %
    source_id: wifi_signal_db
    name: "Wlan Qualität"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "Signal %"
    entity_category: "diagnostic"

### ---------------------------------------------------
## BINARY SENSOR
### ---------------------------------------------------
binary_sensor:
  # simulate led state
  - platform: template
    name: Status Led
    id: statusled
    entity_category: "diagnostic"
    lambda: "return id(current_value) > 0;"

### ---------------------------------------------------
## TEXT SENSOR
### ---------------------------------------------------
text_sensor:
  # device version
  # disabled for api (memory ??)
  - platform: version
    name: Version
    id: appver
    internal: true
    entity_category: "diagnostic"

  # device online time
  # disabled for api (memory ??)
  - platform: template
    name: Online seit
    id: uptime_human
    internal: true
    icon: mdi:clock-start
    entity_category: "diagnostic"

  # waterdisplay last update
  - platform: template
    name: Zählerstand aktualisiert
    id: watermeter_lastupdate
    icon: mdi:clock-start
    entity_category: "diagnostic"

  # device timestamp
  # disabled for api (memory ??)
  - platform: template
    name: Timestamp
    id: systime
    internal: true
    entity_category: "diagnostic"
    lambda: char str[20];
      time_t currTime = id(sntp_time).now().timestamp;
      strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%S", localtime(&currTime));
      return (std::string) str;
# eof water-meter-izar.yaml

from ha-watermeter.

zibous avatar zibous commented on June 15, 2024

@sanchosk

Should work with radio 868 MHz according to OMS standard and there is a driver at wmbusmeters.
see: https://github.com/wmbusmeters/wmbusmeters/blob/master/src/driver_topaseskr.cc

You can ask Szczepan Leon if it is possible to create the driver.
see: https://github.com/SzczepanLeon/esphome-components

from ha-watermeter.

sanchosk avatar sanchosk commented on June 15, 2024

Thanks, 868HMz radio ordered, should arrive in 2 weeks :)

from ha-watermeter.

sanchosk avatar sanchosk commented on June 15, 2024

Hi again. The radio arrived, I've put together quickly the device, but I seem to have a problem.
The meterID gets detected, but afterwards I get message that it "can't get value from telegram ID [0x] 'izar'
The problem, I guess, is the 'izar' part, as my meter uses the wmbus protocol type 'topaseskr'.
I tried to change the type in the sensor -> type, but it does not seem to work.
During boot, the esp reports available drivers, but topaseskr is not listed:
Apr 28 21:14:37 water-meter-esp wmbus [C][wmbus:342]: Available drivers: amiplus, apator08, apator162, apatoreitn, bmeters, elf, evo868, fhkvdataiii, hydrocalm3, itron, izar, mkradio3, mkradio4, qheat, qwater, ultrimis, unismart, vario451

Any idea what am I doing wrong, plz?

from ha-watermeter.

zibous avatar zibous commented on June 15, 2024

hi,

Any idea what am I doing wrong, plz?

from ha-watermeter.

sanchosk avatar sanchosk commented on June 15, 2024

I feel like absolute failure here.
Trying to make your code work with ESP32...
I did try to combine it with the code you provided in your repo, but I am failing miserably.
Below is the code, this is the error:
`INFO Reading configuration /config/esphome/watermeter.yaml...
ERROR Error while reading config: Invalid YAML syntax:

while parsing a block mapping
in "/config/esphome/watermeter.yaml", line 481, column 5:
- platform: wmbus
^
expected , but found ''
in "/config/esphome/watermeter.yaml", line 491, column 6:
rssi:
^
`
I copy-pasted the whole section around wmbus again and again, nothing seems to be helping :(

## ------------------------------------------------------------------
## WMBUS METER D1 MINI + CC1101 for Diehl IZAR RC 868 I R4 PL
##
## usage:  1. Using Homassistant API (discovery + devices)
##         2. External custom component from SzczepanLeon
##
## ------------------------------------------------------------------
substitutions:
  device_name_short: "water-meter-izar"
  device_description: "Wasserzähler Wemos D1 Min, CUL - CC1101, IZAR module (Diehl IZAR RC 868 I R4 PL) simple SzczepanLeon"

  update_interval: 60s
  log_level: "VERBOSE" # use VERBOSE mode to find the meterId 0x43430778
  appversion: "1.1.7"

  domain: !secret domain

esphome:
  name: ${device_name_short}
  comment: ${device_description}
  project:
    name: ${projectname}
    version: ${appversion}
  build_path: ./build/${device_name_short}

  ## ----------------------------------------------------------------
  ## External components for wmbusmeter
  ## ----------------------------------------------------------------
  on_boot:
    # At this priority, pretty much everything should already be initialized.
    priority: -100.0
    then:
      - logger.log:
          level: INFO
          tag: "BOOT"
          format: "BOOTMESSAGE:${device_name_short} API is connected, Device ready!"
      - globals.set:
          id: boot_counter
          value: !lambda "return id(boot_counter)+=1;"

  on_shutdown:
    priority: 600
    then:
      - logger.log:
          level: INFO
          tag: "BOOT"
          format: "BOOTMESSAGE:${device_name_short} is down!"

## ----------------------------------------------------------------
## External components for wmbusmeter
## ----------------------------------------------------------------
external_components:
  # use exterban component 2.0 from
  # https://github.com/SzczepanLeon/esphome-components
  - source: github://SzczepanLeon/esphome-components@main
    refresh: 0d
    components: [ wmbus ]

  # use local component from
  # https://github.com/zdzichu6969/esphome-components
  - source:
      type: github://zdzichu6969/esphome-components
      refresh: 0d
    components: [backup]

  # use local component from
  # https://github.com/TheStaticTurtle/esphome_syslog
  - source:
      type: github://TheStaticTurtle/esphome_syslog
      refresh: 0d
    components: [syslog]

  # use local component from
  # https://github.com/ssieb/custom_components/tree/master/components/heapmon
  # - source:
  #     type: local
  #     path: custom_components
  #   components: [heapmon]

# ----------------------------------------------------------------
# az-delivery-devkit-v4
# ----------------------------------------------------------------
esp32:
  board: az-delivery-devkit-v4
  framework:
    type: arduino


## ----------------------------------------------------------------
## Global variables
## ----------------------------------------------------------------
globals:
  - id: boot_counter
    type: int
    restore_value: yes
    initial_value: "0"

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

  - id: float_default
    type: float
    restore_value: no
    initial_value: "0.00"

  - id: m3toliter
    type: float
    initial_value: "1000.00"
    restore_value: yes

  - 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: month_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"

## ---------------------------------------------------
## WIFI Settings 3 wifis
## ---------------------------------------------------
wifi:
  networks:
    - ssid: !secret wifi_name
      password: !secret wifi_password
      priority: 0
  domain: !secret domain

## ---------------------------------------------------
## The captive portal component in ESPHome is a
## fallback mechanism for when connecting to the
## configured WiFi fails.
## ---------------------------------------------------
captive_portal:

logger:
  id: appslogger
  level: ${log_level}
  baud_rate: 0 #disable logging over uart

## ---------------------------------------------------
## Enable Home Assistant API
## ---------------------------------------------------
## Homeassistant service call:
## service: esphome.water_meter_set_water_val
## data:
##  water_val_hour: 0.03
##  water_val_day: 0.248
##  water_val_yesterday: 0.178
##  water_val_week: 0.248
##  water_val_month: 1.94
##  water_val_year: 14.256
##  water_val_lastmonth: 9.59
## ---------------------------------------------------
api:
  id: espapiwm2_d2
  port: 6053
  reboot_timeout: 0s
  services:
    - service: set_water_val
      variables:
        water_val_hour: float
        water_val_day: float
        water_val_yesterday: float
        water_val_week: float
        water_val_month: 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_LOGI("main", "Set hourly value to: %f", water_val_hour);
                return (water_val_hour);
              }else{
                ESP_LOGI("main", "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_LOGI("main", "Set daily value to: %f", water_val_day);
                return (water_val_day);
              }else{
                ESP_LOGI("main", "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_LOGI("main", "Set yesterday value to: %f", water_val_yesterday);
                return (water_val_yesterday);
              }else{
                ESP_LOGI("main", "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_LOGI("main", "Set weekly value to: %f", water_val_week);
                return (water_val_week);
              }else{
                ESP_LOGI("main", "Skip setting weekly value");
                return id(week_value);
              };
              id(waterweek).publish_state(id(week_value));

        - globals.set:
            id: month_value
            value: !lambda |-
              if((water_val_month) and (water_val_month)>0.001){
                ESP_LOGI("main", "Set last montj value to: %f", water_val_month);
                return (water_val_month);
              }else{
                ESP_LOGI("main", "Skip setting monthly value");
                return id(week_value);
              };
              id(watermonth).publish_state(id(month_value));

        - globals.set:
            id: lastmonth_value
            value: !lambda |-
              if((water_val_lastmonth) and (water_val_lastmonth)>0.001){
                ESP_LOGI("main", "Set last month value to: %f", water_val_lastmonth);
                return (water_val_lastmonth);
              }else{
                ESP_LOGI("main", "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_LOGI("main", "Set last yearly value to: %f", water_val_year);
                return (water_val_year);
              }else{
                ESP_LOGI("main", "Skip setting last yearly value");
                return id(week_value);
              };
              id(wateryear).publish_state(id(year_value));

        - logger.log:
            format: "All new Values set: hour: %.1f, day: %.1f, week: %.1f, month: %.1f, lastmonth: %.1f, year: %.1f"
            args:
              [
                "id(hour_value)",
                "id(daily_value)",
                "id(week_value)",
                "id(month_value)",
                "id(lastmonth_value)",
                "id(year_value)",
              ]

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

## ----------------------------------------------------------------------
## LOCAL WEBSERVER Settings, local settings - no internet
## Include supporting javascript locally allowing it to work
## without internet access.
## ----------------------------------------------------------------------
web_server:
  port: 80
  version: 2
  local: true

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

    on_time_sync:
      then:
        - logger.log: "Synchronized sntp clock"

    # reset hourly value
    on_time:
      - seconds: 0
        minutes: 0
        then:
          - globals.set:
              id: hour_value
              value: "0.00"
          - lambda: id(waterhour).publish_state(id(hour_value));
          - logger.log: 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);
          - lambda: id(wateryesterday).publish_state(id(yesterday_value));
          - lambda: id(daily_value)=0.00;
          - lambda: id(waterday).publish_state(id(daily_value));
          - logger.log: 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: Reset value weekly, starting new week

      # reset monthly value and set last month value
      - seconds: 0
        minutes: 0
        hours: 0
        days_of_month: 1
        then:
          - globals.set:
              id: month_value
              value: "0.00"
          - lambda: id(watermonth).publish_state(id(month_value));
          - lambda: |-
              if(id(waterdisplay).state){
                id(lastmonth_value)=id(waterdisplay).state;
              }
          - logger.log: Reset value monthly, starting new month

      # 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: Reset value yearly, starting new year

## ---------------------------------------------------
## WMBUS DEVICE D1MINI WEMOS
## ---------------------------------------------------
wmbus:
  ## connction to CC1101
  mosi_pin: GPIO23 ## SI:   braun
  miso_pin: GPIO19 ## SO:   grün
  clk_pin: GPIO18 ## SCLK: violett
  cs_pin: GPIO05 ## CSN:  orange
  gdo0_pin: GPIO16 ## GD00: gelb (rx)
  gdo2_pin: GPIO17 ## GD02: weiss (tx)

## ---------------------------------------------------
## SWITCHES
## ---------------------------------------------------
switch:
  # reset boot counter value
  - platform: template
    name: Reset Boot Counter
    turn_on_action:
      then:
        - lambda: |-
            id(boot_counter) = id(int_default);
            id(bootcounter).publish_state(id(boot_counter));
        - logger.log:
            level: INFO
            tag: "BOOT"
            format: "${device_name_short} reset boot counter o.k!"

  # reset all global vars
  - platform: template
    name: Reset values
    turn_on_action:
      then:
        - lambda: |-
            id(last_value) = id(float_default);

            id(boot_counter) = id(int_default);
            id(bootcounter).publish_state(id(boot_counter));

            id(current_value) = id(float_default);
            id(watercurrent).publish_state(id(current_value));

            id(hour_value) = id(float_default);
            id(waterhour).publish_state(id(hour_value));

            id(daily_value) = id(float_default);
            id(waterday).publish_state(id(daily_value));

            id(yesterday_value) = id(float_default);
            id(wateryesterday).publish_state(id(yesterday_value));

            id(week_value) = id(float_default);
            id(waterweek).publish_state(id(week_value));

            id(month_value) = id(float_default);
            id(watermonth).publish_state(id(month_value));

            id(lastmonth_value) = id(float_default);
            id(waterlastmonth).publish_state(id(lastmonth_value));

            id(year_value) = id(float_default);
            id(wateryear).publish_state(id(year_value));

        - logger.log: all values reset!

  - platform: restart
    name: "Restart"
    id: restart_switch


## ---------------------------------------------------
## SENSORS
## ---------------------------------------------------
sensor:
  # water display
  - platform: wmbus
    name: "Wasseruhr Anzeige"
    id: "waterdisplay"
    # Meter ID (usually from sticker). Can be specified as decimal or hex.
    # only hex is working for my watermeter !
    # use meter_id: 0  to see all watermeters
    meter_id: 0 ## !secret watermeterId
    type: topaseskr
    lqi:
      name: "My lqi"
     rssi:
      name: "My RSSI"
    total_water_m3:
        unit_of_measurement: "m³"
        state_class: total_increasing
        device_class: "water"
        accuracy_decimals: 3
        on_value:
          then:
            - lambda: |-
                ESP_LOGI("SENSOR", "Water Display value: %f, last value: %f", id(waterdisplay).state, id(last_value));

                if ((id(last_value) > 0.00) and (id(waterdisplay).state)>(id(last_value)) ) {

                  id(current_value) = (id(waterdisplay).state-id(last_value)) * id(m3toliter);
                  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(month_value)+=id(current_value);
                  id(watermonth).publish_state(id(month_value));

                  id(year_value)+=id(current_value);
                  id(wateryear).publish_state(id(year_value));

                  ESP_LOGI("SENSOR", "Set current value to %f litre and publish the data", id(watercurrent));

                }else{

                  id(current_value) = 0.00;
                  id(watercurrent).publish_state(id(current_value));
                  ESP_LOGI("SENSOR", "Reset current value to: %f", id(watercurrent));

                }
                id(last_value)=id(waterdisplay).state;

            - text_sensor.template.publish:
                id: watermeter_lastupdate
                state: !lambda |-
                  char str[20];
                  time_t currTime = id(sntp_time).now().timestamp;
                  strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%S", localtime(&currTime));
                  return (std::string) str;

  # water current
  - platform: template
    name: Wasser Aktuell
    id: "watercurrent"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: "measurement"
    device_class: "water"
    lambda: |-
      return (id(current_value));

  # water current hour
  - platform: template
    name: Wasser Stunde
    id: "waterhour"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: total_increasing
    device_class: "water"
    lambda: |-
      return (id(hour_value));

  # water today
  - platform: template
    name: Wasser Tag
    id: "waterday"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    device_class: "water"
    state_class: total_increasing
    lambda: |-
      return (id(daily_value));

  # water yesterday
  - platform: template
    name: Wasser Gestern
    id: "wateryesterday"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    device_class: "water"
    state_class: total_increasing
    lambda: |-
      return (id(yesterday_value));

  # water current week
  - platform: template
    name: Wasser Woche
    id: "waterweek"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    device_class: "water"
    state_class: total_increasing
    lambda: |-
      return (id(week_value));

  # water current month
  - platform: template
    name: Wasser Monat
    id: "watermonth"
    accuracy_decimals: 2
    unit_of_measurement: "L"
    state_class: total_increasing
    device_class: "water"
    lambda: |-
      return (id(month_value));

  # water current year
  - 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));

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

  # device boot counter
  - platform: template
    name: Boot counter
    id: bootcounter
    accuracy_decimals: 0
    entity_category: "diagnostic"
    state_class: "measurement"
    lambda: |-
      return (id(boot_counter));

  # device uptime human reading format
  # only internal used
  - platform: uptime
    name: Uptime
    id: uptime_sensor
    internal: true
    update_interval: ${update_interval}
    unit_of_measurement: seconds
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? String(days) + "d " : "") +
                (hours ? String(hours) + "h " : "") +
                (minutes ? String(minutes) + "m " : "") +
                (String(seconds) + "s")
              ).c_str();

  # Wifi quality RSSI
  - platform: wifi_signal
    name: Wlan Signal
    id: wifi_signal_db
    update_interval: 60s
    internal: true
    entity_category: "diagnostic"

  # Wifi quality RSSI in percentage
  - platform: copy # Reports the WiFi signal strength in %
    source_id: wifi_signal_db
    name: "Wlan Qualität"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "Signal %"
    entity_category: "diagnostic"

### ---------------------------------------------------
## BINARY SENSOR
### ---------------------------------------------------
binary_sensor:
  # simulate led state
  - platform: template
    name: Status Led
    id: statusled
    entity_category: "diagnostic"
    lambda: "return id(current_value) > 0;"

### ---------------------------------------------------
## TEXT SENSOR
### ---------------------------------------------------
text_sensor:
  # device version
  # disabled for api (memory ??)
  - platform: version
    name: Version
    id: appver
    internal: true
    entity_category: "diagnostic"

  # device online time
  # disabled for api (memory ??)
  - platform: template
    name: Online seit
    id: uptime_human
    internal: true
    icon: mdi:clock-start
    entity_category: "diagnostic"

  # waterdisplay last update
  - platform: template
    name: Zählerstand aktualisiert
    id: watermeter_lastupdate
    icon: mdi:clock-start
    entity_category: "diagnostic"

  # device timestamp
  # disabled for api (memory ??)
  - platform: template
    name: Timestamp
    id: systime
    internal: true
    entity_category: "diagnostic"
    lambda: char str[20];
      time_t currTime = id(sntp_time).now().timestamp;
      strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%S", localtime(&currTime));
      return (std::string) str;
# eof water-meter-izar.yaml

from ha-watermeter.

zibous avatar zibous commented on June 15, 2024

@sanchosk

Sorry, my mistake. You can try this version:

## ------------------------------------------------------------------
## WMBUS METER D1 MINI + CC1101 for Diehl IZAR RC 868 I R4 PL
##
## this version shows all watermeters. Use this for the first test
##
## Remark:
##   Some Wemos D1 Mini has memory problems, for me one is working
##   another one (same order) reboots with JSON Errors.
##   ESP8266-12F Mini NodeMcu mit ESP8266-12F
## ------------------------------------------------------------------
substitutions:
  device_name_short: "water-meter-test"
  device_description: "Wasserzähler Wemos D1 Min, CUL - CC1101, IZAR module (Diehl IZAR RC 868 I R4 PL (SzczepanLeon) - all watermeters"
  appversion: "2.0.3"
  domain: !secret domain
  update_interval: 60s 
  # use VERBOSE mode to find the meterId and shows all informations for the wbmus
  log_level: "VERBOSE" 

# ----------------------------------------------------------------
# HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
# ----------------------------------------------------------------  
esp8266:
  board: d1_mini
  restore_from_flash: true

esphome:
  name: ${device_name_short}
  comment: ${device_description}
  project:
    name: "OE9psj.wmbus-minid1"
    version: ${appversion}
  build_path: ./build/${device_name_short}
  on_boot:
    # At this priority, pretty much everything should already be initialized.
    priority: -100.0
    then:
      - globals.set:
          id: boot_counter
          value: !lambda "return id(boot_counter)+=1;"
      - logger.log:
          level: INFO
          tag: "BOOT"
          format: "BOOTMESSAGE:${device_name_short} API is connected, Device ready!"
  on_shutdown:
    priority: 700
    then:
      - logger.log:
          level: INFO
          tag: "BOOT"
          format: "BOOTMESSAGE:${device_name_short} is down!"

## ----------------------------------------------------------------
## External components
## ----------------------------------------------------------------
external_components:
  # uses the latest version from SzczepanLeon
  # 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@main
    refresh: 0s
    components: [wmbus]

## ----------------------------------------------------------------
## Global 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"

## ---------------------------------------------------
## WIFI Settings 3 wifis
## ---------------------------------------------------
wifi:
  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

# The captive portal component in ESPHome is a fallback mechanism for
# when connecting to the configured WiFi fails.
captive_portal:

logger:
  id: appslogger
  level: ${log_level}
  baud_rate: 0 #disable logging over uart

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

## ---------------------------------------------------
## LOCAL WEBSERVER Settings
## ---------------------------------------------------
web_server:
  port: 80
  version: 2
  local: true

## ---------------------------------------------------
# Enable Home Assistant API
## ---------------------------------------------------
api:
  id: espapiwm2_d1
  port: 6053
  reboot_timeout: 0s

## ---------------------------------------------------
## SNTP Time server
## ---------------------------------------------------
time:
  - platform: sntp
    id: sntp_time
    timezone: Europe/Berlin
    servers:
      - 0.at.pool.ntp.org
      - 0.pool.ntp.org
      - 1.pool.ntp.org
    on_time_sync:
      then:
        - logger.log: "Synchronized sntp clock"

## ---------------------------------------------------
## WMBUS DEVICE D1MINI WEMOS
## ---------------------------------------------------
wmbus:
  ## ------------------------------------
  ## connction to CC1101 --> D1MINI WEMOS
  ## ------------------------------------
  mosi_pin: GPIO13    #D7  MOSI Attached to Hardware SPI controller MOSI SPI Interface
  miso_pin: GPIO12    #D6  MISO Attached to Hardware SPI controller MISO SPI Interface
  clk_pin: GPIO14     #D5  SCK  Attached to Hardware SPI controller CLK
  cs_pin: GPIO15      #D8  CSN  Attached to Hardware SPI controller, Controls Boot Mode; CS SPI Interface 10k Pull-Down, boot fails if pulled high !!!
  gdo0_pin: GPIO04    #D2  High Impedance !
  gdo2_pin: GPIO05    #D1  High Impedance !


## ---------------------------------------------------
## SWITCHES
## ---------------------------------------------------
switch:
  # reset boot counter value
  - platform: template
    name: Reset Boot Counter
    turn_on_action:
      then:
        - lambda: |-
            id(boot_counter) = 0;
            id(bootcounter).publish_state(id(boot_counter));
        - logger.log:
            level: INFO
            tag: "BOOT"
            format: "${device_name_short} reset boot counter o.k!"
  # restart device
  - platform: restart
    name: "Restart"
    id: restart_switch
  # save device boot (develop only)
  - platform: safe_mode
    name: "Restart (Safe Mode)"
  # reset the device to factory reset (develop only)
  - platform: factory_reset
    name: Restart with Factory Default Settings

## ---------------------------------------------------
## SENSORS
## ---------------------------------------------------
sensor:
  # water display
  - 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
    meter_id: !secret watermeterId
    type: izar
    add_prefix: true
    # 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: "Wlan CC1101 LQI"
      entity_category: "diagnostic"
    # 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.
    rssi:
      id: wmbus_cc1101_rssi
    total_water_m3:
      name: "Wasseruhr Anzeige"
      id: "waterdisplay"
      unit_of_measurement: "m³"
      state_class: total_increasing
      device_class: "water"
      accuracy_decimals: 3
      on_value:
        then:
          - lambda: |-              
              ESP_LOGI("SENSOR", "Water Display value: %f, last value: %f", id(waterdisplay).state, id(last_value));  
              id(last_value)=id(waterdisplay).state;
            
  # device boot counter
  - platform: template
    name: Boot counter
    id: bootcounter
    accuracy_decimals: 0
    state_class: "measurement"
    entity_category: "diagnostic"
    lambda: |-
      return (id(boot_counter));

  # Wifi quality RSSI
  # only internal used (memory bug D1MINI ??)
  - platform: wifi_signal
    name: Wlan Signal
    id: wifi_signal_db
    update_interval: 60s
    internal: true
    entity_category: "diagnostic"

  # Wifi quality RSSI in percentage
  # # Received Signal Strength (RSSI) is a measure of incoherent (raw) RF power in a channel.
  - platform: copy # Reports the WiFi signal strength in %
    source_id: wifi_signal_db
    name: "Wlan ESP32 Qualität"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "Signal %"
    entity_category: "diagnostic"

  # CC1101 quality RSSI in percentage
  # Received Signal Strength (RSSI) is a measure of incoherent (raw) RF power in a channel.
  - platform: copy
    source_id: wmbus_cc1101_rssi
    name: "Wlan CC1101 RSSI"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "Signal %"
    entity_category: "diagnostic"

from ha-watermeter.

zibous avatar zibous commented on June 15, 2024

solved, see:
SzczepanLeon/esphome-components#18

from ha-watermeter.

sanchosk avatar sanchosk commented on June 15, 2024

@zibous Do you have some "thank you coffee" option?

from ha-watermeter.

zibous avatar zibous commented on June 15, 2024

@sanchosk

Do you have some "thank you coffee" option?

Thanks yes, i like and need coffe...
https://www.buymeacoffee.com/zibous

Grüße vom Bodensee...

from ha-watermeter.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.