344 lines
8.2 KiB
YAML
344 lines
8.2 KiB
YAML
substitutions:
|
|
name: thr320d_filtre_bb04f0
|
|
friendly_name: Filtration"
|
|
project_name: "Filtration piscine"
|
|
project_version: "1.0"
|
|
light_restore_mode: RESTORE_DEFAULT_OFF
|
|
|
|
esphome:
|
|
name: "${name}"
|
|
# supply the external temp/hum sensor with 3v power by pulling this GPIO high
|
|
on_boot:
|
|
- priority: 90
|
|
then:
|
|
- switch.turn_on: ${name}_sensor_power
|
|
|
|
esp32:
|
|
board: nodemcu-32s
|
|
|
|
api:
|
|
encryption:
|
|
key: "zOAo/IyJfGlFafVzPae/pCJZQtGFRWc7i+O9ZXfRY+c="
|
|
|
|
ota:
|
|
- platform: esphome
|
|
password: "5e0d993d03804b33e56142c07cae7526"
|
|
|
|
logger:
|
|
baud_rate: 0
|
|
|
|
web_server:
|
|
port: 80
|
|
version: 3
|
|
log: off
|
|
ota: off
|
|
local: true
|
|
auth:
|
|
username: !secret web_server_user_piscine
|
|
password: !secret web_server_pass_piscine
|
|
|
|
wifi:
|
|
ssid: !secret wifi_ssid
|
|
password: !secret wifi_password
|
|
|
|
|
|
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
|
ap:
|
|
ssid: !secret ap_ssid_pool
|
|
password: !secret ap_pass_pool
|
|
|
|
captive_portal:
|
|
|
|
one_wire:
|
|
- platform: gpio
|
|
pin: GPIO25
|
|
|
|
# This will take care of the display automatically.
|
|
# You don't need to tell it to print something to the display manually.
|
|
# It'll update every 60s or so.
|
|
display:
|
|
platform: tm1621
|
|
id: tm1621_display
|
|
cs_pin: GPIO17
|
|
data_pin: GPIO5
|
|
read_pin: GPIO23
|
|
write_pin: GPIO18
|
|
lambda: |-
|
|
it.printf(0, "%.1f", id(${name}_temp).state);
|
|
it.display_celsius(true);
|
|
if (id(sntp_time).now().is_valid()) {
|
|
it.printf(1, "%1.f", id(duree).state);
|
|
}
|
|
|
|
binary_sensor:
|
|
# single main button that also puts device into flash mode when held on boot
|
|
- platform: gpio
|
|
pin:
|
|
number: GPIO0
|
|
mode: INPUT_PULLUP
|
|
inverted: True
|
|
name: "Boutton"
|
|
internal: True
|
|
on_click:
|
|
- min_length: 500ms # long press
|
|
max_length: 2s
|
|
then:
|
|
- switch.toggle: mainRelayVirt
|
|
- min_length: 5s # very long press to reset
|
|
max_length: 10s
|
|
then:
|
|
- switch.turn_on: ${name}_restart
|
|
on_double_click:
|
|
then:
|
|
switch.toggle: dryContRelay
|
|
|
|
switch:
|
|
# virtual switch to represent the main relay
|
|
# as far as I know, we have no way to confirm the real state
|
|
- platform: template
|
|
id: mainRelayVirt
|
|
name: "Pompe"
|
|
turn_on_action:
|
|
- switch.turn_on: mainRelayOn
|
|
- switch.turn_on: ${name}_pompe_led
|
|
turn_off_action:
|
|
- switch.turn_on: mainRelayOff
|
|
- switch.turn_off: ${name}_pompe_led
|
|
assumed_state: True
|
|
optimistic: True
|
|
icon: mdi:pump
|
|
web_server_sorting_weight: 10
|
|
|
|
# internal momentary switch for main relay ON
|
|
- platform: gpio
|
|
id: mainRelayOn
|
|
internal: True
|
|
pin:
|
|
number: GPIO19
|
|
on_turn_on:
|
|
- delay: 500ms
|
|
- switch.turn_off: mainRelayOn
|
|
restore_mode: ALWAYS_OFF
|
|
|
|
# internal momentary switch for main relay OFF
|
|
- platform: gpio
|
|
id: mainRelayOff
|
|
internal: True
|
|
pin:
|
|
number: GPIO22
|
|
on_turn_on:
|
|
- delay: 500ms
|
|
- switch.turn_off: mainRelayOff
|
|
restore_mode: ALWAYS_OFF
|
|
|
|
# dry contact relay switch
|
|
- platform: gpio
|
|
id: dryContRelay
|
|
name: "Sortie auxiliaire"
|
|
icon: mdi:cards-diamond
|
|
web_server_sorting_weight: 15
|
|
pin:
|
|
number: GPIO4
|
|
on_turn_on:
|
|
- switch.turn_on: ${name}_aux_led
|
|
on_turn_off:
|
|
- switch.turn_off: ${name}_aux_led
|
|
restore_mode: ALWAYS_OFF
|
|
|
|
# Leftmost (red) LED that's used to indicate the relay being on/off
|
|
- platform: gpio
|
|
id: ${name}_pompe_led
|
|
pin:
|
|
number: GPIO16
|
|
inverted: true
|
|
|
|
# Rightmost (green) LED; use as dry contact indicator
|
|
- platform: gpio
|
|
id: ${name}_aux_led
|
|
pin:
|
|
number: GPIO13
|
|
inverted: true
|
|
|
|
# This is needed to power the external temp/humidity sensor.
|
|
# It receives 3v from this pin, which is pulled up on boot.
|
|
# TODO: This should probably be an internal switch.
|
|
- platform: gpio
|
|
pin: GPIO27
|
|
id: ${name}_sensor_power
|
|
restore_mode: ALWAYS_OFF
|
|
|
|
- platform: restart
|
|
name: "Redémarrer"
|
|
id: ${name}_restart
|
|
icon: "mdi:restart"
|
|
|
|
|
|
sensor:
|
|
- platform: dallas_temp
|
|
name: "Température eau"
|
|
id: ${name}_temp
|
|
address: 0xfe3ce504578d3c28
|
|
update_interval: 1s
|
|
web_server_sorting_weight: 05
|
|
icon: mdi:pool-thermometer
|
|
|
|
text_sensor:
|
|
- platform: wifi_info
|
|
ip_address:
|
|
name: "Addresse IP"
|
|
disabled_by_default: true
|
|
icon: mdi:ip-network
|
|
|
|
number:
|
|
- platform: template
|
|
name: "Heure démarrage"
|
|
id: heure_depart
|
|
min_value: 0
|
|
max_value: 59
|
|
step: 1
|
|
restore_value: True
|
|
initial_value: 8
|
|
unit_of_measurement: s
|
|
mode: box
|
|
optimistic: True
|
|
icon: mdi:clock-start
|
|
web_server_sorting_weight: 20
|
|
|
|
- platform: template
|
|
name: "Durée de base"
|
|
id: duree_debase
|
|
min_value: 0
|
|
max_value: 60
|
|
step: 1
|
|
restore_value: False
|
|
initial_value: 0
|
|
unit_of_measurement: s
|
|
optimistic: True
|
|
internal: True
|
|
|
|
- platform: template
|
|
name: "Durée filtration H/j"
|
|
id: duree
|
|
min_value: 0
|
|
max_value: 60
|
|
step: 1
|
|
restore_value: False
|
|
initial_value: 0
|
|
unit_of_measurement: s
|
|
mode: SLIDER
|
|
optimistic: True
|
|
entity_category: config
|
|
icon: mdi:fan-clock
|
|
web_server_sorting_weight: 25
|
|
|
|
- platform: template
|
|
name: "Heure actuelle"
|
|
id: heure
|
|
internal: True
|
|
min_value: 0
|
|
max_value: 59
|
|
step: 1
|
|
unit_of_measurement: s
|
|
optimistic: True
|
|
|
|
- platform: template
|
|
name: "Heure fin filtration"
|
|
id: heure_fin
|
|
internal: True
|
|
min_value: 0
|
|
max_value: 59
|
|
step: 1
|
|
unit_of_measurement: s
|
|
optimistic: True
|
|
|
|
select:
|
|
- platform: template
|
|
name: "Mode"
|
|
id: mode
|
|
optimistic: true
|
|
options:
|
|
- Forcé
|
|
- Intensif
|
|
- Normal
|
|
- Économique
|
|
- Arrêt
|
|
initial_option: Normal
|
|
icon: mdi:power
|
|
web_server_sorting_weight: 2
|
|
on_value:
|
|
then:
|
|
- lambda: |-
|
|
if (id(mode).state == "Intensif") {
|
|
id(duree).state = id(duree_debase).state + 2;
|
|
if (id(duree).state > 59) {
|
|
id(duree).state = 60;
|
|
}
|
|
}
|
|
if (id(mode).state == "Normal") {
|
|
id(duree).state = id(duree_debase).state;
|
|
}
|
|
if (id(mode).state == "Économique") {
|
|
id(duree).state = id(duree_debase).state - 2;
|
|
if (id(duree).state < 0) {
|
|
id(duree).state = 0;
|
|
}
|
|
}
|
|
|
|
time:
|
|
- platform: sntp
|
|
id: sntp_time
|
|
timezone: Europe/Paris
|
|
servers:
|
|
- 0.pool.ntp.org
|
|
- 1.pool.ntp.org
|
|
- 2.pool.ntp.org
|
|
|
|
|
|
interval:
|
|
- interval: 1s
|
|
then:
|
|
- lambda: |-
|
|
if (id(mode).state == "Forcé") {
|
|
id(mainRelayVirt).turn_on();
|
|
}
|
|
|
|
if ((id(mode).state == "Normal") || (id(mode).state == "Économique") || (id(mode).state == "Intensif")) {
|
|
if (id(sntp_time).now().second == (id(heure_depart).state)) {
|
|
id(duree_debase).state = (id(${name}_temp).state / 2);
|
|
id(duree).state = id(duree_debase).state;
|
|
}
|
|
|
|
ESP_LOGI("main", "Heure de début: %.0f", id(heure_depart).state);
|
|
id(heure_fin).state = id(heure_depart).state + (id(duree).state) -1;
|
|
ESP_LOGI("main", "Heure de fin: %.0f", id(heure_fin).state);
|
|
if (id(heure_fin).state > 59) {
|
|
id(heure_fin).state = id(heure_fin).state - 60;
|
|
}
|
|
ESP_LOGI("main", "Heure de fin: %.0f", id(heure_fin).state);
|
|
if (id(heure_fin).state >= id(heure_depart).state) {
|
|
if (((id(sntp_time).now().second) >= (id(heure_depart).state)) and ((id(sntp_time).now().second) <= (id(heure_fin).state))) {
|
|
id(mainRelayVirt).turn_on();
|
|
}
|
|
else {
|
|
id(mainRelayVirt).turn_off();
|
|
}
|
|
}
|
|
else {
|
|
if ((id(sntp_time).now().second) >= (id(heure_depart).state)) {
|
|
id(mainRelayVirt).turn_on();
|
|
}
|
|
else {
|
|
if ((id(sntp_time).now().second) <= (id(heure_fin).state)) {
|
|
id(mainRelayVirt).turn_on();
|
|
}
|
|
else {
|
|
id(mainRelayVirt).turn_off();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (id(mode).state == "Arrêt") {
|
|
id(mainRelayVirt).turn_off();
|
|
}
|