Closed acca84 closed 10 months ago
Hi, 1) Can you share the code you use ? It's difficult to have a look at the pin you are using without it.
2) Are your reed switch connected between GPIO and GND or GPIO and +3.3V
3) Have a look at https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/ to see which pin are safe to use (not used during boot and not high at BOOT)
Hi, i moved to esp32 miniS2 since i had rebbots each 45minutes with Lolin D1 mini and since i red that esp32 was best for pulse counting. I still have the same problem. both sensor have one wire to ground, the other to pin 16 for sensor 1 and 17 for sensor 2.
My code is the following (sorry i don't manage to show it as code) :
substitutions:
name: Compteur eau froide
friendly_name: "Froide"
friendly_nameC: "Chaude"
esphome:
name: esp-compteur-eau
friendly_name: Cpt eau
platform: ESP32
board: lolin_s2_mini
#variant: esp32s2
on_boot:
priority: -10
then:
- script.execute:
publish_states
- script.execute:
publish_states_chaud
ota:
password: "PASSOTA"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esp-Compteur-Eau"
password: "PASSS"
captive_portal:
# Enable Home Assistant API
api:
encryption:
key: "BwlakwbxY2t2BF1+713lxiWUaGJe7jPXYlANIOsyjHg="
services:
- service: reset_main_counter
then:
- script.execute: reset_main_counter
- service: reset_secondary_counter
then:
- script.execute: reset_secondary_counter
- service: reset_main_counter_chaud
then:
- script.execute: reset_main_counter_chaud
- service: reset_secondary_counter_chaud
then:
- script.execute: reset_secondary_counter_chaud
logger:
level: INFO # Flashing effect generate too many debug log
# Documentations:
# https://github.com/esphome/issues/issues/664
# https://esphome.io/components/sensor/integration.html
# https://community.home-assistant.io/t/using-esphome-to-build-a-water-flow-rate-meter/119380/64
globals:
- id: main_counter_pulses
type: int
restore_value: yes
initial_value: '0'
- id: secondary_counter_pulses
type: int
restore_value: yes
initial_value: '0'
- id: daily_counter_pulses
type: int
restore_value: yes
initial_value: '0'
- id: weekly_counter_pulses
type: int
restore_value: yes
initial_value: '0'
- id: monthly_counter_pulses
type: int
restore_value: yes
initial_value: '0'
- id: yearly_counter_pulses
type: int
restore_value: yes
initial_value: '0'
- id: event_quantity
type: int
restore_value: no
initial_value: '0'
- id: last_event_quantity
type: int
restore_value: no
initial_value: '0'
- id: event_counter
type: int
restore_value: no
initial_value: '0'
- id: current_event_quantity
type: int
restore_value: no
initial_value: '0'
- id: main_counter_pulses_chaud
type: int
restore_value: yes
initial_value: '0'
- id: secondary_counter_pulses_chaud
type: int
restore_value: yes
initial_value: '0'
- id: daily_counter_pulses_chaud
type: int
restore_value: yes
initial_value: '0'
- id: weekly_counter_pulses_chaud
type: int
restore_value: yes
initial_value: '0'
- id: monthly_counter_pulses_chaud
type: int
restore_value: yes
initial_value: '0'
- id: yearly_counter_pulses_chaud
type: int
restore_value: yes
initial_value: '0'
- id: event_quantity_chaud
type: int
restore_value: no
initial_value: '0'
- id: last_event_quantity_chaud
type: int
restore_value: no
initial_value: '0'
- id: event_counter_chaud
type: int
restore_value: no
initial_value: '0'
- id: current_event_quantity_chaud
type: int
restore_value: no
initial_value: '0'
script:
- id: reset_main_counter
then:
- lambda: |-
id(main_counter_pulses) = 0;
id(water_main_consumption).publish_state(id(main_counter_pulses));
- id: reset_secondary_counter
then:
- lambda: |-
id(secondary_counter_pulses) = 0;
id(water_secondary_consumption).publish_state(id(secondary_counter_pulses));
- id: reset_main_counter_chaud
then:
- lambda: |-
id(main_counter_pulses_chaud) = 0;
id(water_main_consumption_chaud).publish_state(id(main_counter_pulses_chaud));
- id: reset_secondary_counter_chaud
then:
- lambda: |-
id(secondary_counter_pulses_chaud) = 0;
id(water_secondary_consumption_chaud).publish_state(id(secondary_counter_pulses_chaud));
- id: publish_states
then:
- lambda: |-
id(water_main_consumption).publish_state(id(main_counter_pulses));
id(water_secondary_consumption).publish_state(id(secondary_counter_pulses));
id(water_daily_consumption).publish_state(id(daily_counter_pulses));
id(water_weekly_consumption).publish_state(id(weekly_counter_pulses));
id(water_monthly_consumption).publish_state(id(monthly_counter_pulses));
id(water_yearly_consumption).publish_state(id(yearly_counter_pulses));
id(current_water_consumption).publish_state(id(event_quantity));
- id: publish_states_chaud
then:
- lambda: |-
id(water_main_consumption_chaud).publish_state(id(main_counter_pulses_chaud));
id(water_secondary_consumption_chaud).publish_state(id(secondary_counter_pulses_chaud));
id(water_daily_consumption_chaud).publish_state(id(daily_counter_pulses_chaud));
id(water_weekly_consumption_chaud).publish_state(id(weekly_counter_pulses_chaud));
id(water_monthly_consumption_chaud).publish_state(id(monthly_counter_pulses_chaud));
id(water_yearly_consumption_chaud).publish_state(id(yearly_counter_pulses_chaud));
id(current_water_consumption_chaud).publish_state(id(event_quantity_chaud));
sensor:
- platform: uptime
name: "Compteur eau uptime"
- platform: wifi_signal
name: "Compteur eau WiFi signal"
# TCRT5000 pulse counter
# IO16 / GPIO16
- platform: pulse_counter
id: water_pulse_counter
name: "${friendly_name} debit"
pin:
number : 16
allow_other_uses: true
mode:
input: true
pullup: true
update_interval: 2sec
internal_filter: 10us
unit_of_measurement: "L/min"
accuracy_decimals: 0
icon: "mdi:water"
filters:
# Divide by 60
#- multiply: 0.0167
- lambda: return abs(x);
# Value calculated are not consistent
#- platform: integration
# id: water_integration_sensor
# name: "${friendly_name} integrated water consumption"
# sensor: water_pulse_counter
# time_unit: min
# unit_of_measurement: "L"
# accuracy_decimals: 0
# icon: "mdi:water"
- platform: template
id: water_main_consumption
name: "${friendly_name} consommation principale"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: water_secondary_consumption
name: "${friendly_name} consommation secondaire"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: water_daily_consumption
name: "${friendly_name} consommation journaliere"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: water_weekly_consumption
name: "${friendly_name} consommation hebdomadaire"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: water_monthly_consumption
name: "${friendly_name} consommation mensuelle"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: water_yearly_consumption
name: "${friendly_name} consommation annuelle"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: current_water_consumption
name: "${friendly_name} consommation actuelle"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: last_water_consumption
name: "${friendly_name} consommation precedente"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
# TCRT5000 pulse counter CHAUD
# IO18 / GPIO16
- platform: pulse_counter
id: water_pulse_counter_chaud
name: "${friendly_nameC} debit"
pin:
number : GPIO17
allow_other_uses: true
mode:
input: true
pullup: true
update_interval: 2sec
internal_filter: 10us
unit_of_measurement: "L/min"
accuracy_decimals: 0
icon: "mdi:water"
filters:
# Divide by 60
#- multiply: 0.0167
- lambda: return abs(x*10);
# Value calculated are not consistent
#- platform: integration
# id: water_integration_sensor
# name: "${friendly_name} integrated water consumption"
# sensor: water_pulse_counter
# time_unit: min
# unit_of_measurement: "L"
# accuracy_decimals: 0
# icon: "mdi:water"
- platform: template
id: water_main_consumption_chaud
name: "${friendly_nameC} consommation principale"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: water_secondary_consumption_chaud
name: "${friendly_nameC} secondary water consumption"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: water_daily_consumption_chaud
name: "${friendly_nameC} consommation journaliere"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: water_weekly_consumption_chaud
name: "${friendly_nameC} consommation hebdomadaire"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: water_monthly_consumption_chaud
name: "${friendly_nameC} consommation mensuelle"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: water_yearly_consumption_chaud
name: "${friendly_nameC} consommation annuelle"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: current_water_consumption_chaud
name: "${friendly_nameC} consommation actuelle"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
- platform: template
id: last_water_consumption_chaud
name: "${friendly_nameC} consommation precedente"
unit_of_measurement: "L"
accuracy_decimals: 0
icon: "mdi:water"
binary_sensor:
# TCRT5000 pulse counter
# IO18 / GPIO16
- platform: gpio
id: water_pulse
pin:
number : 16
allow_other_uses: true
mode:
input: true
pullup: true
internal: true
filters:
- delayed_on_off: 50ms
- lambda: |-
id(main_counter_pulses) += x;
id(secondary_counter_pulses) += x;
id(daily_counter_pulses) += x;
id(weekly_counter_pulses) += x;
id(monthly_counter_pulses) += x;
id(yearly_counter_pulses) += x;
id(event_quantity) += x;
return x;
on_state:
- script.execute: publish_states
# TCRT5000 pulse counter CHAUD
# IO18 / GPIO16
- platform: gpio
id: water_pulse_chaud
pin:
number : GPIO17
allow_other_uses: true
mode:
input: true
pullup: true
internal: true
filters:
- delayed_on_off: 50ms
- lambda: |-
id(main_counter_pulses_chaud) += 10*x;
id(secondary_counter_pulses_chaud) += 10*x;
id(daily_counter_pulses_chaud) += 10*x;
id(weekly_counter_pulses_chaud) += 10*x;
id(monthly_counter_pulses_chaud) += 10*x;
id(yearly_counter_pulses_chaud) += 10*x;
id(event_quantity_chaud) +=10*x;
return x;
on_state:
- script.execute: publish_states_chaud
switch:
- platform: template
name: "${friendly_name} reset main counter button"
icon: "mdi:restart"
turn_on_action:
- script.execute: reset_main_counter
- platform: template
name: "${friendly_name} reset secondary counter button"
icon: "mdi:restart"
turn_on_action:
- script.execute: reset_secondary_counter
- platform: template
name: "${friendly_nameC} reset main counter button"
icon: "mdi:restart"
turn_on_action:
- script.execute: reset_main_counter_chaud
- platform: template
name: "${friendly_nameC} reset secondary counter button"
icon: "mdi:restart"
turn_on_action:
- script.execute: reset_secondary_counter_chaud
- platform: restart
name: "Compteur eau restart"
time:
- platform: sntp
on_time:
- seconds: 0
minutes: 0
hours: 0
then:
- globals.set:
id: daily_counter_pulses
value: '0'
- globals.set:
id: daily_counter_pulses_chaud
value: '0'
- lambda: |-
id(water_daily_consumption).publish_state(id(daily_counter_pulses));
id(water_daily_consumption_chaud).publish_state(id(daily_counter_pulses_chaud));
- seconds: 0
minutes: 0
hours: 0
days_of_week: MON
then:
- globals.set:
id: weekly_counter_pulses
value: '0'
- globals.set:
id: weekly_counter_pulses_chaud
value: '0'
- lambda: |-
id(water_weekly_consumption).publish_state(id(weekly_counter_pulses));
id(water_weekly_consumption_chaud).publish_state(id(weekly_counter_pulses_chaud));
- seconds: 0
minutes: 0
hours: 0
days_of_month: 1
then:
- globals.set:
id: monthly_counter_pulses
value: '0'
- globals.set:
id: monthly_counter_pulses_chaud
value: '0'
- lambda: |-
id(water_monthly_consumption).publish_state(id(monthly_counter_pulses));
id(water_monthly_consumption_chaud).publish_state(id(monthly_counter_pulses_chaud));
- seconds: 0
minutes: 0
hours: 0
days_of_month: 1
months: JAN
then:
- globals.set:
id: yearly_counter_pulses
value: '0'
- globals.set:
id: yearly_counter_pulses_chaud
value: '0'
- lambda: |-
id(water_yearly_consumption).publish_state(id(yearly_counter_pulses));
id(water_yearly_consumption_chaud).publish_state(id(yearly_counter_pulses_chaud));
interval:
# Save the last consumption
#
# An event is published when a water flow (>= 1L / 15 seconds) is
# detected and followed by a stop of consumption for a defined time.
- interval: 15sec
then:
- lambda: |-
if (id(event_quantity) != id(last_event_quantity)) {
// Water continues to flow
// Reset event counter
id(event_counter) = 0;
} else {
// Water no longer flows
if (id(event_quantity)) {
// 4 * 15 * 5 = 5min
if (id(event_counter) < 4 * 5) {
// Timeout is not reaches
id(event_counter)++;
} else {
// Timeout is reaches
id(last_water_consumption).publish_state(id(event_quantity));
// Send event to Home Assistant
api::HomeAssistantServiceCallAction<> *api;
api = new api::HomeAssistantServiceCallAction<>(api_apiserver, true);
// Event id length limit is 32 characters
api->set_service("esphome.last_consumption_changes");
api->play();
id(event_quantity) = 0;
}
}
}
id(last_event_quantity) = id(event_quantity);
if (id(event_quantity_chaud) != id(last_event_quantity_chaud)) {
// Water continues to flow
// Reset event counter
id(event_counter_chaud) = 0;
} else {
// Water no longer flows
if (id(event_quantity_chaud)) {
// 4 * 15 * 5 = 5min
if (id(event_counter_chaud) < 4 * 5) {
// Timeout is not reaches
id(event_counter_chaud)++;
} else {
// Timeout is reaches
id(last_water_consumption_chaud).publish_state(id(event_quantity_chaud));
// Send event to Home Assistant
api::HomeAssistantServiceCallAction<> *api;
api = new api::HomeAssistantServiceCallAction<>(api_apiserver, true);
// Event id length limit is 32 characters
api->set_service("esphome.last_consumption_changes_chaud");
api->play();
id(event_quantity_chaud) = 0;
}
}
}
id(last_event_quantity_chaud) = id(event_quantity_chaud);
# Track the current consumption
- interval: 2sec
then:
- lambda: |-
if (id(event_quantity) != id(current_event_quantity)) {
id(current_water_consumption).publish_state(id(event_quantity));
}
id(current_event_quantity) = id(event_quantity);
if (id(event_quantity_chaud) != id(current_event_quantity_chaud)) {
id(current_water_consumption_chaud).publish_state(id(event_quantity_chaud));
}
id(current_event_quantity_chaud) = id(event_quantity_chaud);
Do not publish any passwords !!
To share code you can use the <> icon
Thanks, that's what i was doing, but i had to paste my code then to click <>
Concerning pins high at boot, it seams that those pins are safe : https://www.studiopieters.nl/esp32-s2-pinout/
I'm sorry, I didn't check correctly, I have no more problem with esp32s2. So i think I used wrong pins with esp8266
I have modified your code and implemented my two counters, it seams to work well, thank for your work.
But i have noticed something : if i reboot the esp8266, the main counters (i have two, one for cold water, one for hot water) are incremented by 1.
I'd like them not to be incremented I don't use the same kind of sensor, I use reed sensors (only two wires, dry contact), so i declare their pins input pull-up, could that be the cause ?
I mean because pin goes high when declared, so it increments the counter. But I would imagine nothing happens before pin definition are finished (as in Arduino void setup() ) Thanks again