petsie
September 15, 2021, 4:07pm
1
I use globals variable to set the initial value of sensors.
globals:
- id: z61count
type: int
restore_value: yes
initial_value: "0"
- id: z61counter
type: float
restore_value: yes
initial_value: "0.000"
- id: m3kw
type: float
restore_value: yes
initial_value: "10.94"
- id: gas_meter_displayvalue
binary_sensor:
- platform: gpio
pin code:
number: GPIO12
mode: INPUT_PULLUP
inverted: false
name: $ {friendly_name} gas meter Z-61 pulse
id: gas sensor_state
device_class: window
filters:
- delayed_off: 10ms
on_release:
then:
- lambda: | -
id (z61counter) + = $ {impulsfactor};
id (z61count) + = 1;
id (gas_meter_totalm3) + = $ {impulsfactor};
id (gas_meter_displayvalue) + = $ {impulsfactor};
id (daily_value) + = $ {impulsfactor};
id (gas_meter_display) .update ();
id (gas_meter_total_m3) .update ();
id (gas_meter_total_kw) .update ();
id (gas_meter_total_kw_day) .update ();
The disadvantage here is that if this value is no longer correct, then I would like to change it. A change before compiling is not accepted.
How could I reset this initial value via an MQTT command or via API?
So far I have not found a solution for this and would be happy if someone can give me a tip on how I could do it.
In HA you will need input helpers for your globals.
In your ESPHome file you can set up user defined api services for each of the globals you need to set:
api:
services:
- service: set_z61count
variables:
my_count: int
then:
- globals.set:
id: z61count
value: !lambda 'return my_count;'
Then in HA you can attach a call service to a button or whatever trigger method you want to use:
service: esphome.device_name_set_z61count
data:
my_count: "{{ states('input_number.z61count_manual') }}"
petsie
September 16, 2021, 9:53am
3
@Didgeridrew
Thanks, this is working but:
If API is enabled i can not use MQTT, because the device has on start a lot of boot error and will restart every 5min.
But ESPHOME MQTT
generally causes massive problems, because even without API it occasionally
reboots,
WIFI is also very unstable,
OTA updates do not always work …
Regardless of which device ESP32, ESP8266, … always the same problem.
If I don’t use MQTT, i.e. only API methods, then all devices work without problems.
It looks as if the MQTT implementation only causes problems and cannot be used for productive use with ESPHOME devices.
Testcase:
## #######################################################################################
## D! MINI - HEIZUNG 2021 - SENSOREN
## #######################################################################################
## DONOT USE MQTT AND API:
## [W][ota:036]: Last Boot was an unhandled reset, will proceed to safe mode in 8 restarts
## device will also reboot all 5min .... !!!!
## used PINS on D1 MINI
##
## GPI012: ✔︎ D6 - DS18B20 4 x Digital temperature sensor
## GPIO14: ✔︎ D7 - WATERMETER binary_sensor reed contact sensor
## SCL,SDA ✔︎ D1, D2 ADS1115
## A0: MQ2 GAS SENSIR
## A1: DFRobot SEN0257 Analog Water Pressure Sensor
## A2: DFRobot SEN0257 Analog Water Pressure Sensor
## A3: DFRobot SEN0257 Analog Water Pressure Sensor
##
## ----------------------------------------------------------------
substitutions:
board: d1_mini
platform: ESP8266
device_name_short: "wmt" # used by esp-home config
friendly_name: "Heizung" # label name
update_interval: 60s
impulsfactor: "0.250"
appversion: "1.1.4"
device_description: "Heizungssensoren Temperatur, Wasserdruck, Wasserzähler, Luftqualität"
esphome:
name: ${device_name_short}
comment: ${device_description}
platform: ${platform}
board: ${board}
esp8266_restore_from_flash: true
project:
name: "OE9psj.d1MiniWmt"
version: ${appversion}
on_boot:
priority: -100.0
then:
- logger.log: ${device_name_short} is connected!
- globals.set:
id: boot_counter
value: !lambda "return id(boot_counter)+=1;"
on_shutdown:
then:
- logger.log: ${device_name_short} is down!
# ----------------------------------------------------------------
# set wifi,ota,web_server, time
# ----------------------------------------------------------------
<<: !include common/wifi.yaml
# ----------------------------------------------------------------
# logger component
# ----------------------------------------------------------------
logger:
level: DEBUG
baud_rate: 19200
# ----------------------------------------------------------------
# all used globals variables
# ----------------------------------------------------------------
globals:
- id: boot_counter
type: int
restore_value: yes
initial_value: "0"
- id: water_meter_impulse
type: float
restore_value: yes
initial_value: "0.000"
- id: water_meter_sum
type: float
restore_value: yes
initial_value: "0.000"
- id: water_meter_display
type: float
restore_value: yes
initial_value: "8.249"
- id: daily_value
type: float
restore_value: yes
initial_value: "0.000"
# ----------------------------------------------------------------
# Homeassistant API calls
# ----------------------------------------------------------------
api:
services:
- service: set_water_meter_display
variables:
my_newdisplayvalue: int
then:
- globals.set:
id: water_meter_display
value: !lambda "return my_newdisplayvalue * 0.001;"
- logger.log: gas_meter_displayvalue has now new value!
# ----------------------------------------------------------------
# Sun component
# ----------------------------------------------------------------
sun:
id: sun_sun
latitude: !secret home_latitude
longitude: !secret home_longitude
on_sunrise:
- then:
- logger.log: Good morning!
- elevation: 5°
then:
- logger.log: Good morning 2!
on_sunset:
- then:
- logger.log: Good evening!
# ----------------------------------------------------------------
# Switch to restart
# ----------------------------------------------------------------
switch:
- platform: restart
id: restart_device
name: ${friendly_name} restart
# ----------------------------------------------------------------
# D7 Watermeter counter GPI013
# Simple pulscounter
# ----------------------------------------------------------------
binary_sensor:
- platform: gpio
pin:
number: D7
mode: INPUT_PULLUP
inverted: false
name: ${friendly_name} Warmwasser Impuls
id: heatingwater_meter_state
device_class: window
filters:
- delayed_off: 10ms
on_release:
then:
- lambda: |-
id(water_meter_sum) += ${impulsfactor};
id(water_meter_impulse) += 1;
id(water_meter_display) += ${impulsfactor}/1000;
id(daily_value) += ${impulsfactor};
id(water_meterdisplay).update();
id(water_meter_liter).update();
id(water_meter_counter).update();
id(water_meter_total_liter_day).update();
sensor:
# ----------------------------------------------------------------
# testcase pulscounter
# ----------------------------------------------------------------
- platform: pulse_meter
id: water_pulse_meter
pin:
number: D7
mode: INPUT_PULLUP
internal_filter: 2s
timeout: 30 sec
unit_of_measurement: "m³"
name: ${friendly_name} water
state_class: measurement
accuracy_decimals: 3
filters:
- multiply: 0.250
total:
name: ${friendly_name} water consumption
unit_of_measurement: "m³"
device_class: gas
state_class: total_increasing
accuracy_decimals: 3
icon: mdi:gauge
filters:
- multiply: 0.250
# ----------------------------------------------------------------
# watermeter data
# ----------------------------------------------------------------
- platform: template
name: ${friendly_name} Warmwasser Anzeige
id: water_meterdisplay
accuracy_decimals: 3
unit_of_measurement: "m³"
update_interval: 30s
lambda: |-
return (id(water_meter_display));
- platform: template
name: ${friendly_name} Warmwasser Liter
id: water_meter_liter
accuracy_decimals: 3
unit_of_measurement: "l"
update_interval: 30s
lambda: |-
return (id(water_meter_sum));
- platform: template
name: ${friendly_name} Warmwasser Einheiten
id: water_meter_counter
accuracy_decimals: 0
update_interval: 30s
lambda: |-
return (id(water_meter_impulse));
- platform: template
name: ${friendly_name} Warmwasser heute
id: water_meter_total_liter_day
unit_of_measurement: "l"
lambda: |-
return (id(daily_value));
# -----------------------------------------------
# sensor wifi_signal
# -----------------------------------------------
- platform: wifi_signal
name: ${friendly_name} WiFi Signal
id: heating_wifi_signal
update_interval: 60s
- platform: template
name: ${friendly_name} Boot counter
id: bootcounter
accuracy_decimals: 0
lambda: |-
return (id(boot_counter));
# -----------------------------------------------
# sensor updtime and MQTT Publish task
# -----------------------------------------------
- platform: uptime
name: ${friendly_name} Uptime
id: uptime_sensor
update_interval: ${update_interval}
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();
# -----------------------------------------------
# Text sensors...
# -----------------------------------------------
text_sensor:
- platform: sun
name: ${friendly_name} Nächster Sonnenaufgang
id: sunup
type: sunrise
- platform: sun
name: ${friendly_name} Nächster Sonnenuntergang
id: sundown
type: sunset
- platform: version
name: ${friendly_name} Version
id: appver
- platform: template
name: ${friendly_name} Online seit
id: uptime_human
icon: mdi:clock-start
- platform: wifi_info
ip_address:
name: ${friendly_name} IP
id: wifiip
icon: mdi:ip-network
ssid:
name: ${friendly_name} SSID
id: wifissid
bssid:
id: wifibssid
name: ${friendly_name} BSSID
- platform: template
name: ${friendly_name} Timestamp
id: systime
lambda: |-
char str[20];
time_t currTime = id(sntp_time).now().timestamp;
strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", localtime(&currTime));
return (std::string) str;
It’s been a while since I did anything with MQTT (I moved all my Tasmota devices to ESPHome because I had so many issues with MQTT)… but if you need MQTT for you project, I think what you are looking for is the Subscribe Sensor . I can’t remember if payload is passed the same way as with the on_message action (as ‘x’), but try something like:
sensor:
- platform: mqtt_subscribe
name: "z61count Manual Set"
id: set_z61count
topic: the/topic
on_value:
then:
- globals.set:
id: z61count
value: !lambda 'return x;'
From HA you just publish as usual:
service: mqtt.publish
data:
topic: the/topic
payload: 56
According to the docs, the subscribe sensor expects a float in the payload, so make sure you convert it as needed on the device before setting the global.
petsie
September 16, 2021, 12:37pm
5
Hi,
Thanks.
Now i have moved alle my ESP Devices from MQTT to API and all works w/o any problems (crossing the fingers…). Tasmota works for me.
I am currently looking at the project “aioesphomeapi”.
see: https://github.com/esphome/aioesphomeapi
With this I could set up an MQTT service with python or set up processing without a home assistant (fallback solution). But I have not yet found out how I can set value via the aioesphomeapi API, reading all sensor data works perfectly.
The InfluxDBClient integration is also nice there.
I can only confirm that MQTT causes massive problems with ESPHome and therefore I cannot recommend its use with ESP devices.
Hi, I have a similar problem as petsie. Sometimes I need to set a correct value for my gas sensor. Using initial_value and restore_values in ESPHOME doesn’t allow me to re-initialise a value with “restore_values: yes”. I tried Didgeridrew’s approach, but how can I create a button on the Dashboard, where I get an input box to input the new value? I can create a button with a fixed value with this code:
show_name: true
show_icon: true
type: button
tap_action:
action: call-service
service: esphome.d1mini_1_set_zaehlerstand
data:
new_zaehlerstand: 10000
target: {}
name: Neuer Zählerstand
view_layout:
position: sidebar
icon: mdi:counter
show_state: false
But I want to get a popup where I can input the new value.
petsie
September 26, 2022, 9:34am
7
@patrick0815
see: How to update a globals variable - #2 by Didgeridrew
I use the developer tools - services:
based on:
# ----------------------------------------------------------------
# Native API Component
# ----------------------------------------------------------------
api:
id: espapi
port: 6053
reboot_timeout: 5min
services:
- service: set_gasmeterdisplay
variables:
my_newdisplayvalue: float
then:
- logger.log:
format: "Setting Gasmeter Display value: %.1f"
args: [my_newdisplayvalue]
- globals.set:
id: gas_meter_displayvalue
value: !lambda "return (my_newdisplayvalue);"
- logger.log:
format: "Gasmeter Display value: %.1f"
args: [id(gas_meter_displayvalue)]
Thanks petsie! That’s a good way to do this. I already implemented the API on the ESP. Do you know, if it is possible with a button in the dashboard, which displays a popup dialog box to input the new value?
petsie
September 26, 2022, 3:12pm
9
No, I don’t know - just the way via the service call or a Lovelace Card with an input field and button.