Home Assistant ESP32 Robotti-imurin käynnistys releellä
ESP32n koodi:
esphome:
name: robot2
esp32:
board: mhetesp32minikit
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "T8lbN/mj+xxJcGRnYcdVCWDh4aGOUBKAA+1y8+ut8wM="
ota:
- platform: esphome
password: "f76aa4ecb929327969ea7c0567839087"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 192.168.1.110
gateway: 192.168.1.1
subnet: 255.255.255.0
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Robot2 Fallback Hotspot"
password: "5Lf8XVYmqCl4"
captive_portal:
switch:
- platform: gpio
name: "KYTKINR2"
pin: 16
inverted: False
restore_mode: RESTORE_DEFAULT_OFF
Imurin automaatiot:
- id: '1742839773020'
alias: Robot 2 Start to vacum
description: ''
triggers:
- trigger: state
entity_id:
- input_button.start_vacuum
from:
conditions: []
actions:
- sequence:
- type: turn_on
device_id: f46a1851c8924e532596ac5cfc4f8356
entity_id: 7dba5e29c23b5cde41d06ef8e28ff155
domain: switch
- delay:
hours: 0
minutes: 0
seconds: 1
milliseconds: 0
- action: switch.turn_off
metadata: {}
data: {}
target:
entity_id: switch.kytkinr2
mode: single
- id: '1742840644556'
alias: Robot 2 time to clean
description: ''
triggers:
- trigger: time
at: input_datetime.robot_2_time
conditions:
- condition: template
value_template: '{{ now().weekday() in [3, 5] }}'
actions:
- action: automation.trigger
metadata: {}
data:
skip_condition: true
target:
entity_id: automation.robot_2_start_to_vacum
mode: single
Home Assistant ESP32 Liesituuletin
Huomasin jälkeenpäin, että sisääntulot on paras eristää optisesti. Liesikuvun rajakytkin ehti rikkoa suoraan kytketyn inputin, vaikka painike toimi moitteetta. Syynä on ilmeisesti mikrokytkimen huono suojaus ja siitä syntyvät ylijännitepiikit; pelkkä pulldown-vastus ei auttanut. Lisäsin sisääntulojen eteen releet, eikä häiriö enää pääse vaurioittamaan elektroniikkaa. Laitan myöhemmin kuvan kytkennästä.
ESP32n koodi:
esphome:
name: liesituuletin
friendly_name: Liesituuletin
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "wb9G2GeoRdi0f6yKWphQqolwfEqhGLkw3Ar9pFWo0Uk="
ota:
- platform: esphome
password: "8751b2228cd287410e301b0aa7b91460"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 192.168.1.112
gateway: 192.168.1.1
subnet: 255.255.255.0
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Liesituuletin Fallback Hotspot"
password: "dlRviN1IILuN"
captive_portal:
switch:
- platform: gpio
name: "LT-Valo"
pin: 32
inverted: False
restore_mode: RESTORE_DEFAULT_OFF
- platform: gpio
name: "LT-T1"
pin: 33
inverted: False
restore_mode: RESTORE_DEFAULT_OFF
- platform: gpio
name: "LT-T2"
pin: 25
inverted: False
restore_mode: RESTORE_DEFAULT_OFF
- platform: gpio
name: "LT-T3"
pin: 26
inverted: False
restore_mode: RESTORE_DEFAULT_OFF
binary_sensor:
- platform: gpio
pin:
number: 19
mode: INPUT_PULLUP
name: "Huuva"
device_class: opening
filters:
- invert:
- delayed_on: 50ms
- delayed_off: 50ms
- platform: gpio
pin:
number: 5
mode: INPUT_PULLUP
name: "Power"
device_class: opening
filters:
- invert:
- delayed_on: 50ms
- delayed_off: 50ms
sensor:
- platform: dht
pin: 21
model: DHT22
temperature:
name: "Lämpötila Huuva"
humidity:
name: "Kosteus Huuva"
update_interval: 6s
Liesituulettimen Automaatiot:
- id: '1745089202276'
alias: LIESI - Valo
description: ''
triggers:
- type: opened
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: cf2a5d78b221d1c674e4e7bc65f11d23
domain: binary_sensor
trigger: device
- type: not_opened
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: cf2a5d78b221d1c674e4e7bc65f11d23
domain: binary_sensor
trigger: device
conditions: []
actions:
- if:
- type: is_open
condition: device
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: cf2a5d78b221d1c674e4e7bc65f11d23
domain: binary_sensor
then:
- type: turn_on
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: a01b8a72147e981776abc67366f8f237
domain: switch
else:
- type: turn_off
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: a01b8a72147e981776abc67366f8f237
domain: switch
mode: single
- id: '1745091641469'
alias: LIESI - Syötön päälle laitto
description: ''
triggers:
- trigger: state
entity_id:
- binary_sensor.liesituuletin_huuva
from:
- trigger: state
entity_id:
- timer.liesi_aika
to: idle
- type: opened
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: 7d55476b80cf26df67250d12886baa9d
domain: binary_sensor
trigger: device
- type: not_opened
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: 7d55476b80cf26df67250d12886baa9d
domain: binary_sensor
trigger: device
conditions: []
actions:
- if:
- condition: and
conditions:
- condition: state
entity_id: binary_sensor.liesituuletin_huuva
state: 'on'
- type: is_temperature
condition: device
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: f57c06e691a2238beff9a2ecafa6cf2d
domain: sensor
below: 80
- condition: or
conditions:
- condition: state
entity_id: timer.liesi_aika
state: active
- type: is_open
condition: device
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: 7d55476b80cf26df67250d12886baa9d
domain: binary_sensor
then:
- action: switch.turn_on
metadata: {}
data: {}
target:
entity_id: switch.liesi
else:
- action: switch.turn_off
metadata: {}
data: {}
target:
entity_id: switch.liesi
mode: single
- id: '1745091959952'
alias: LIESI - TIMERI
description: ''
triggers:
- type: opened
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: cf2a5d78b221d1c674e4e7bc65f11d23
domain: binary_sensor
trigger: device
conditions: []
actions:
- action: timer.start
metadata: {}
data: {}
target:
entity_id: timer.liesi_aika
mode: single
- id: '1745093289166'
alias: LIESI - Kokkaaminen liian kallista, ylilämpö tai PALO
description: ''
triggers:
- trigger: state
entity_id:
- sensor.nordpool_kwh_fi_eur_10_10_0255
from:
- trigger: state
entity_id:
- sensor.liesituuletin_l_mp_tila_huuva
conditions: []
actions:
- if:
- condition: or
conditions:
- condition: numeric_state
entity_id: sensor.nordpool_kwh_fi_eur_10_10_0255
above: 0.2
- type: is_temperature
condition: device
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: f57c06e691a2238beff9a2ecafa6cf2d
domain: sensor
above: 60
- condition: and
conditions:
- type: is_temperature
condition: device
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: f57c06e691a2238beff9a2ecafa6cf2d
domain: sensor
above: 60
- type: is_humidity
condition: device
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: ab2fcf8c37206288024c8462112f52bf
domain: sensor
below: 1
alias: PALO
then:
- action: automation.turn_off
metadata: {}
data:
stop_actions: true
target:
entity_id:
- automation.liesi_paalle_laitto
- automation.liesi_timeri
- action: switch.turn_off
metadata: {}
data: {}
target:
entity_id: switch.liesi
else:
- action: automation.turn_on
metadata: {}
data: {}
target:
entity_id:
- automation.liesi_paalle_laitto
- automation.liesi_timeri
mode: single
- id: '1234567890'
alias: LIESI - LT1-3
description: Kytkee tuuletinnopeudet tarkkojen kosteustasojen mukaan
triggers:
- entity_id: sensor.liesituuletin_kosteus_huuva
trigger: state
- type: opened
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: cf2a5d78b221d1c674e4e7bc65f11d23
domain: binary_sensor
trigger: device
conditions: []
actions:
- if:
- type: is_open
condition: device
device_id: 1bec4ae8ee9a09c1148d7e626234df49
entity_id: cf2a5d78b221d1c674e4e7bc65f11d23
domain: binary_sensor
then:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.liesituuletin_kosteus_huuva
below: 48.9
sequence:
- action: switch.turn_off
metadata: {}
data: {}
target:
entity_id:
- switch.liesituuletin_lt_t1
- switch.liesituuletin_lt_t2
- switch.liesituuletin_lt_t3
- conditions:
- condition: numeric_state
entity_id: sensor.liesituuletin_kosteus_huuva
above: 49
below: 69.9
sequence:
- target:
entity_id: switch.liesituuletin_lt_t1
action: switch.turn_on
data: {}
- action: switch.turn_off
metadata: {}
data: {}
target:
entity_id:
- switch.liesituuletin_lt_t2
- switch.liesituuletin_lt_t3
- conditions:
- condition: numeric_state
entity_id: sensor.liesituuletin_kosteus_huuva
above: 70
below: 89.9
sequence:
- target:
entity_id: switch.liesituuletin_lt_t2
action: switch.turn_on
data: {}
- action: switch.turn_off
metadata: {}
data: {}
target:
entity_id:
- switch.liesituuletin_lt_t1
- switch.liesituuletin_lt_t3
- conditions:
- condition: numeric_state
entity_id: sensor.liesituuletin_kosteus_huuva
above: 90
sequence:
- target:
entity_id: switch.liesituuletin_lt_t3
action: switch.turn_on
data: {}
- action: switch.turn_off
metadata: {}
data: {}
target:
entity_id:
- switch.liesituuletin_lt_t1
- switch.liesituuletin_lt_t2
else:
- action: switch.turn_off
metadata: {}
data: {}
target:
entity_id:
- switch.liesituuletin_lt_t2
- switch.liesituuletin_lt_t1
- switch.liesituuletin_lt_t3
mode: single
Home Assistant ESP32 Liesituuletin ilman assistanttia Standalone
Tällä liesituuletin toimii ilman Home Assistanttia. Eli:
- Liesituuletin menee kosteuden mukaan eri asetuksiin
- Valo menee päälle, kun huuvan aukaisee ja menee pois päältä 60 minuutin päästä
- Lieden syöttö kannattaa tässä laittaa päälle, kun valo on päällä & huuva on auki & lämpötila on alle 50
- Tai jos haluat helpottaa asiaa, niin lieden syöttö on silloin päällä, kun valo on päällä.
esphome:
name: heatmoisture32
friendly_name: HeatMoisture32
esp32:
board: esp32dev
framework:
type: esp-idf
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "sxMeMDktASd3HbXHg2+vI/9JgA7p4oJ7sgck5WV5s0Q="
ota:
- platform: esphome
password: "5d16be6948890fbcb045b4bbc3d34695"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 192.168.1.116
gateway: 192.168.1.1
subnet: 255.255.255.0
ap:
ssid: "Heatmoisture32 Fallback Hotspot"
password: "pogulGFhDJuj"
captive_portal:
# --- Muokkaa näitä arvoja yhdestä paikasta ---
globals:
- id: temp_threshold
type: float
initial_value: '21.0'
- id: humidity_threshold
type: float
initial_value: '60.0'
- id: temp_hysteresis
type: float
initial_value: '0.1'
- id: humidity_hysteresis
type: float
initial_value: '0.1'
# ------------------------------------------------
switch:
- platform: gpio
name: "vara"
pin: 17
inverted: True
restore_mode: RESTORE_DEFAULT_OFF
id: vara_switch
- platform: gpio
name: "Kompura"
pin: 15
inverted: True
restore_mode: RESTORE_DEFAULT_OFF
id: kompura_switch
- platform: gpio
name: "Heat"
pin: 18
inverted: True
restore_mode: RESTORE_DEFAULT_OFF
id: heat_switch
- platform: gpio
name: "Start"
pin: 19
inverted: True
restore_mode: RESTORE_DEFAULT_OFF
id: start_switch
- platform: template
name: "EN"
id: en_switch
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
sensor:
- platform: dht
pin: 21
model: DHT22
update_interval: 6s
temperature:
id: lampotila_HM
name: "Lämpötila HM"
humidity:
id: kosteus_HM
name: "Kosteus HM"
interval:
- interval: 6s
then:
- lambda: |-
const float temp = id(lampotila_HM).state;
const float hum = id(kosteus_HM).state;
const bool valid_temp = !isnan(temp);
const bool valid_hum = !isnan(hum);
if (!id(en_switch).state) {
id(start_switch).turn_off();
id(kompura_switch).turn_off();
id(heat_switch).turn_off();
return;
}
// HEAT: hysteresis
if (valid_temp) {
if (temp < (id(temp_threshold) - id(temp_hysteresis))) {
id(heat_switch).turn_on();
} else if (temp >= id(temp_threshold)) {
id(heat_switch).turn_off();
}
} else {
id(heat_switch).turn_off();
}
// KOMPURA: hysteresis
if (valid_hum) {
if (hum > (id(humidity_threshold) + id(humidity_hysteresis))) {
id(kompura_switch).turn_on();
} else if (hum <= id(humidity_threshold)) {
id(kompura_switch).turn_off();
}
} else {
id(kompura_switch).turn_off();
}
// START: päälle vain jos molemmat anturit kelvollisia ja HEAT tai KOMPURA on päällä
if (valid_temp && valid_hum && (id(heat_switch).state || id(kompura_switch).state)) {
id(start_switch).turn_on();
} else {
id(start_switch).turn_off();
}
Home Assistant ESP32, kosteuden poistaja ja lämmitin. Automaatio ESP:ssä ja lupa HomeAssistantista.
ESP32 wroom
esphome:
name: heatmoisture32
friendly_name: HeatMoisture32
esp32:
board: esp32dev
framework:
type: esp-idf
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "sxMeMDktASd3HbXHg2+vI/9JgA7p4oJ7sgck5WV5s0Q="
ota:
- platform: esphome
password: "5d16be6948890fbcb045b4bbc3d34695"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 192.168.1.116
gateway: 192.168.1.1
subnet: 255.255.255.0
ap:
ssid: "Heatmoisture32 Fallback Hotspot"
password: "pogulGFhDJuj"
captive_portal:
# --- Muokkaa näitä arvoja yhdestä paikasta ---
globals:
- id: temp_threshold
type: float
initial_value: '21.0'
- id: humidity_threshold
type: float
initial_value: '60.0'
- id: temp_hysteresis
type: float
initial_value: '0.1'
- id: humidity_hysteresis
type: float
initial_value: '0.1'
# ------------------------------------------------
switch:
- platform: gpio
name: "vara"
pin: 17
inverted: True
restore_mode: RESTORE_DEFAULT_OFF
id: vara_switch
- platform: gpio
name: "Kompura"
pin: 15
inverted: True
restore_mode: RESTORE_DEFAULT_OFF
id: kompura_switch
- platform: gpio
name: "Heat"
pin: 18
inverted: True
restore_mode: RESTORE_DEFAULT_OFF
id: heat_switch
- platform: gpio
name: "Start"
pin: 19
inverted: True
restore_mode: RESTORE_DEFAULT_OFF
id: start_switch
- platform: template
name: "EN"
id: en_switch
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
sensor:
- platform: dht
pin: 21
model: DHT22
update_interval: 6s
temperature:
id: lampotila_HM
name: "Lämpötila HM"
humidity:
id: kosteus_HM
name: "Kosteus HM"
interval:
- interval: 6s
then:
- lambda: |-
const float temp = id(lampotila_HM).state;
const float hum = id(kosteus_HM).state;
const bool valid_temp = !isnan(temp);
const bool valid_hum = !isnan(hum);
if (!id(en_switch).state) {
id(start_switch).turn_off();
id(kompura_switch).turn_off();
id(heat_switch).turn_off();
return;
}
// HEAT: hysteresis
if (valid_temp) {
if (temp < (id(temp_threshold) - id(temp_hysteresis))) {
id(heat_switch).turn_on();
} else if (temp >= id(temp_threshold)) {
id(heat_switch).turn_off();
}
} else {
id(heat_switch).turn_off();
}
// KOMPURA: hysteresis
if (valid_hum) {
if (hum > (id(humidity_threshold) + id(humidity_hysteresis))) {
id(kompura_switch).turn_on();
} else if (hum <= id(humidity_threshold)) {
id(kompura_switch).turn_off();
}
} else {
id(kompura_switch).turn_off();
}
// START: päälle vain jos molemmat anturit kelvollisia ja HEAT tai KOMPURA on päällä
if (valid_temp && valid_hum && (id(heat_switch).state || id(kompura_switch).state)) {
id(start_switch).turn_on();
} else {
id(start_switch).turn_off();
}
Sitten pitää antaa ESP:een EN-switchille vain käsky HomeAssistantista, että se voi mennä päälle. Itse tein vain automaation, että kun sähkön hinta on kaikkinensa alle 0,15 senttiä, niin laite saa mennä päälle.
- id: '1761507912269'
alias: Kylpyhuoneen HM
description: ''
triggers:
- trigger: state
entity_id:
- sensor.nordpool_kwh_fi_eur_10_10_0255
conditions: []
actions:
- if:
- condition: numeric_state
entity_id: sensor.nordpool_kwh_fi_eur_10_10_0255
below: 0.15
then:
- type: turn_on
device_id: b00e27d77c9db2aa7f59fdbf30a7ef90
entity_id: a9b3d54df472cb0b4e12e6271041a1d7
domain: switch
else:
- type: turn_off
device_id: b00e27d77c9db2aa7f59fdbf30a7ef90
entity_id: a9b3d54df472cb0b4e12e6271041a1d7
domain: switch
mode: single
- id: '1761774163581'
alias: Restart
description: ''
triggers:
- trigger: time
at: '23:30:00'
weekday:
- sun
- mon
- tue
- wed
- thu
- fri
- sat
conditions: []
actions:
- action: hassio.host_reboot
metadata: {}
data: {}
mode: single
Home Assistant ESP32, WC, Standalone
esphome:
name: wc1k
friendly_name: WC1k
on_boot:
priority: -100
then:
- delay: 10s
- lambda: |-
id(boot_ready) = true;
esp32:
board: esp32dev
framework:
type: esp-idf
logger:
api:
encryption:
key: "dwTs6psCg6DptpESE9X592cmp/rju67fizVilVBQCLw="
ota:
- platform: esphome
password: "4dc33851fc30d99628d02d6086cd701d"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Wc1K Fallback Hotspot"
password: "Zesoxt9B6l4u"
captive_portal:
i2c:
sda: 21
scl: 22
scan: true
id: bus_a
####################
# GLOBALS
####################
globals:
- id: boot_ready
type: bool
restore_value: no
initial_value: 'false'
- id: wc_kosteus
type: float
restore_value: no
initial_value: '0.0'
- id: wc_valo
type: float
restore_value: no
initial_value: '0.0'
- id: wc_ultra_osumat
type: int
restore_value: no
initial_value: '0'
- id: pistorasia_paalla
type: bool
restore_value: no
initial_value: 'false'
####################
# SENSORIT
####################
sensor:
- platform: bme680
i2c_id: bus_a
address: 0x77
update_interval: 10s
temperature:
name: "WC Lämpötila"
on_value:
then:
- if:
condition:
lambda: |-
return x < 22.0;
then:
- switch.turn_on: lattialammitys
else:
- switch.turn_off: lattialammitys
pressure:
name: "WC Ilmanpaine"
humidity:
name: "WC Kosteus"
on_value:
then:
- lambda: |-
id(wc_kosteus) = x;
- script.execute: paivita_pistorasia
- if:
condition:
lambda: |-
return x > 70.0;
then:
- switch.turn_on: poistopuhallus
else:
- switch.turn_off: poistopuhallus
gas_resistance:
name: "WC Kaasu"
- platform: adc
pin: 35
id: wc_valaistus_raw
name: "WC Valaistus RAW"
attenuation: 11db
update_interval: 100ms
filters:
- sliding_window_moving_average:
window_size: 3
on_value:
then:
- lambda: |-
id(wc_valo) = x;
- script.execute: paivita_pistorasia
- if:
condition:
lambda: |-
return !id(boot_ready);
then:
- switch.turn_off: musa1_chopinrain
- switch.turn_off: musa6_rain
- if:
condition:
lambda: |-
return id(boot_ready) && x > 0.5;
then:
- switch.turn_off: musa1_chopinrain
- switch.turn_off: musa6_rain
- if:
condition:
lambda: |-
return id(boot_ready) && x <= 0.5;
then:
- if:
condition:
switch.is_on: valo
then:
- switch.turn_off: musa6_rain
- switch.turn_on: musa1_chopinrain
else:
- switch.turn_off: musa1_chopinrain
- switch.turn_on: musa6_rain
- platform: pulse_width
pin: 34
id: wc_echo_raw
name: "WC Ultrasonic Echo Raw"
update_interval: 200ms
- platform: template
id: wc_echo_avg
name: "WC Ultrasonic Echo AVG"
update_interval: 200ms
lambda: |-
if (!id(wc_echo_raw).has_state()) return NAN;
float x = id(wc_echo_raw).state;
if (x < 0.0006 || x > 0.0030) return NAN;
return x;
filters:
- median:
window_size: 5
- sliding_window_moving_average:
window_size: 3
send_every: 1
on_value:
then:
- if:
condition:
lambda: |-
return id(boot_ready) && x < 0.0024;
then:
- lambda: |-
id(wc_ultra_osumat)++;
else:
- lambda: |-
id(wc_ultra_osumat) = 0;
- if:
condition:
lambda: |-
return id(wc_ultra_osumat) >= 3;
then:
- lambda: |-
id(wc_ultra_osumat) = 0;
- script.execute: valo_1min
####################
# ULTRAÄÄNI – TRIG
####################
interval:
- interval: 200ms
then:
- lambda: |-
id(jsn_trig).turn_on();
delayMicroseconds(10);
id(jsn_trig).turn_off();
####################
# SCRIPTIT
####################
script:
- id: valo_1min
mode: restart
then:
- switch.turn_on: valo
- delay: 60s
- switch.turn_off: valo
- id: paivita_pistorasia
mode: queued
then:
- lambda: |-
if (!id(boot_ready)) return;
if (!id(pistorasia_paalla)) {
if (id(wc_kosteus) < 63.0 && id(wc_valo) < 0.4) {
id(pistorasia_paalla) = true;
id(pistorasia).turn_on();
}
} else {
if (id(wc_kosteus) > 67.0 || id(wc_valo) > 0.5) {
id(pistorasia_paalla) = false;
id(pistorasia).turn_off();
}
}
####################
# KYTKIMET
####################
switch:
- platform: gpio
id: jsn_trig
internal: true
pin: 12
- platform: gpio
id: valo
name: "Valo"
pin: 25
restore_mode: RESTORE_DEFAULT_OFF
- platform: gpio
id: pistorasia
name: "Pistorasia"
pin: 26
restore_mode: ALWAYS_OFF
- platform: gpio
id: lattialammitys
name: "Lattialämmitys"
pin: 32
- platform: gpio
id: poistopuhallus
name: "Poistopuhallus"
pin: 33
####################
# MUSIIKIT (KAIKKI)
####################
- platform: gpio
id: musa1_chopinrain
name: "musa1_ChopinRain"
pin: 4
inverted: true
- platform: gpio
id: musa2_dune
name: "musa2_DUNE"
pin: 5
inverted: true
- platform: gpio
id: musa3_goddune
name: "musa3_GODdune"
pin: 16
inverted: true
- platform: gpio
id: musa4_interstellar
name: "musa4_Interstellar"
pin: 17
inverted: true
- platform: gpio
id: musa5_creepremix
name: "musa5_CreepRemix"
pin: 18
inverted: true
- platform: gpio
id: musa6_rain
name: "musa6_RAIN"
pin: 19
inverted: true
- platform: gpio
id: musa7_teknobathroom
name: "musa7_Teknobathroom2069"
pin: 23
inverted: true
- platform: gpio
id: musa8_tyler
name: "musa8_TylerPhilosophy"
pin: 27
inverted: true
Home Assistant Kello
Laita Configuration.yaml tiedostoon, niin saat kellon toimimaan:
- platform: time_date
display_options:
- 'time'
- 'date'
- 'date_time'
- 'date_time_utc'
- 'date_time_iso'
- 'time_date'
- 'time_utc'
- 'beat'
Home Assistant sähkön kustannussensori
Tällä saadaan päiväsähkö, yösähkö, ALV ja sähkön marginaali:
template:
- sensor:
- name: "Hetkellinen sähkön kustannus"
unit_of_measurement: "€/h"
state: >
{% set alv_kerroin = (states('input_number.alv') | float(25.5)) / 100 + 1 %}
{% set hinta = (states('sensor.nordpool_kwh_fi_eur_3_10_0') | float(0)) * alv_kerroin %}
{% set teho = states('sensor.p1_meter_power') | float(0) %}
{% set siirtohinta = states('input_number.yosahko') | float(0.035)
if now().hour >= 22 or now().hour < 6
else states('input_number.paivasahko') | float(0.045) %}
{% set marginaalihinta = (states('input_number.sahkon_marginaalihinta') | float(0)) * alv_kerroin %}
{{ ((hinta + siirtohinta + marginaalihinta) * teho) | round(4) }}
icon: mdi:currency-eur

Home Assistant APEX-kortti 48h Nordpool näkymä
type: custom:apexcharts-card
graph_span: 48h
apex_config:
chart:
height: 170px
show:
last_updated: true
experimental:
color_threshold: true
header:
title: NordPool+Siirto/kWh 48 h
show: true
show_states: true
colorize_states: true
span:
start: day
now:
show: true
label: Nyt
series:
- entity: sensor.nordpool_kwh_fi_eur_10_10_0255
show:
extremas: true
in_header: raw
header_color_threshold: true
type: column
data_generator: |
const today = entity.attributes.raw_today.map((start, index) => {
return [new Date(start["start"]).getTime(), Math.round(entity.attributes.raw_today[index]["value"] * 1000) / 1000];
});
const tomorrow = entity.attributes.raw_tomorrow
? entity.attributes.raw_tomorrow.map((start, index) => {
return [new Date(start["start"]).getTime(), Math.round(entity.attributes.raw_tomorrow[index]["value"] * 1000) / 1000];
})
: [];
return [...today, ...tomorrow];
float_precision: 3
color_threshold:
- value: 0
color: darkgreen
opacity: 1
- value: 0.1
color: goldenrod
- value: 0.32
color: darkred
yaxis:
- id: Hinta
min: ~0
decimals: 2
align_to: 0.05
show: true
Home Assistant RPI_GPIO HAT Raspberry pi
Tässä Raspberry pi:n 8 releiselle boardille
switch:
- platform: rpi_gpio
switches:
- port: 5
name: "KIUAS"
invert_logic: true
- port: 6
name: "LIESI"
invert_logic: true
- port: 13
name: "3-VAIHEPISTORASIA"
invert_logic: true
- port: 16
name: "ET 6 kW"
invert_logic: true
- port: 19
name: "ET 5,1 kW"
invert_logic: true
- port: 20
name: "ET 3,6 kWy"
invert_logic: true
- port: 21
name: "LVV"
invert_logic: true
- port: 26
name: "Öljypoltin"
invert_logic: true
Home Assistant Kustannussensori
Tässä templetti jossa yhdistetään kaikki kulut
template:
- sensor:
- name: "Hetkellinen sähkön kustannus"
unit_of_measurement: "€/h"
state: >
{% set alv_kerroin = (states('input_number.alv') | float(25.5)) / 100 + 1 %}
{% set hinta = (states('sensor.nordpool_kwh_fi_eur_3_10_0') | float(0)) * alv_kerroin %}
{% set teho = states('sensor.p1_meter_power') | float(0) %}
{% set siirtohinta = states('input_number.yosahko') | float(0.035)
if now().hour >= 22 or now().hour < 6
else states('input_number.paivasahko') | float(0.045) %}
{% set marginaalihinta = (states('input_number.sahkon_marginaalihinta') | float(0)) * alv_kerroin %}
{{ ((hinta + siirtohinta + marginaalihinta) * teho) | round(4) }}
icon: mdi:currency-eur
Silloin saat tuon uuden Hetkellisen sähkön kustannuksen ja luo nuo 4 eri helpperiä, että saat numerot templateen.
– input_number.paivasahko
– input_number.yosahko
– input_number.alv
– input_number.sahkon_marginaalihinta

Home Assistant ESP32 Pannun pumppujen ohjaus
Tässä templetti jossa yhdistetään kaikki kulut
# =========================================================
# SÄÄDETTÄVÄT ASETUKSET
# Muuta näitä arvoja tarpeen mukaan - ei tarvitse koskea
# alempana olevaan logiikkaan.
# =========================================================
substitutions:
# Absoluuttiset lämpötilarajat (pumpun pakko-ohjaus)
on_limit: "26.0" # °C - tämän yli pumppu AINA päälle
off_limit: "23.0" # °C - tämän alle pumppu saa mennä pois (jos turvallista)
# Nopea, lyhyen ikkunan nousuntunnistus (esim. äkillinen liekki)
rise_threshold_fast: "0.5" # °C
rise_window_fast_ms: "60000" # 60 000 ms = 1 min
# Hidas/herkkä nousuntunnistus - KÄYNNISTÄÄ PUMPUN AIKAISEMMIN
# Esim. 0.3 astetta 2 minuutissa -> pumppu käynnistyy heti kun
# nousu ylittyy, ei tarvitse odottaa koko ikkunan täyttymistä.
rise_threshold_slow: "0.3" # °C
rise_window_slow_ms: "120000" # 120 000 ms = 2 min
# Pumpun käyntiaika kun se laukeaa ajastimella
pump_runtime_ms: "2700000" # 2 700 000 ms = 45 min
# Kuinka kauan anturivian jälkeen odotetaan ennen kuin
# OFF-ehto sallitaan uudelleen (turvamarginaali)
recovery_hold_ms: "120000" # 120 000 ms = 2 min
# Kuinka kauan ilman kelvollista lukemaa ennen kuin
# anturi tulkitaan vikaantuneeksi
sensor_timeout_ms: "30000" # 30 000 ms = 30 s
# Kuinka kauan lämpötila saa pysyä alle off_limit-rajan
# (eikä pumpun ajastin ole käynnissä) ennen kuin annetaan
# "lisää puuta pannuun" -ilmoitus (VIIMEINEN VARMISTIN,
# laukeaa vasta kun tuli on jo aika lailla hiipunut)
low_temp_alert_delay_ms: "300000" # 300 000 ms = 5 min
# AIKAINEN VAROITUS: jos lämpötila laskee tämän verran
# tämän ikkunan sisällä, annetaan "lisää puuta" -ilmoitus
# HETI - riippumatta absoluuttisesta lämpötilasta. Näin
# ilmoitus tulee jo silloin kun tuli alkaa hiipua, ei vasta
# kun lämpötila on ehtinyt pudota off_limit-rajan alle.
fall_threshold: "0.3" # °C
fall_window_ms: "5400000" # 300 000 ms = 5 min
# PYSÄHTYMISEN (STAGNAATION) TUNNISTUS
# Jos lämpötila pysyy tämän kaistan sisällä (ei nouse eikä laske
# merkittävästi) yhtäjaksoisesti tämän ajan, pumppu SAMMUTETAAN
# vaikka lämpötila olisi vielä yli off_limit-rajan. Tulkitaan,
# ettei lämpöä ole enää tulossa lisää (tuli hiipunut / paluuvesi
# tasaantunut), joten latausta ei ole enää järkevää jatkaa.
stagnation_band: "0.2" # °C - tämän sisällä pysyminen tulkitaan "ei muutosta"
stagnation_window_ms: "900000" # 900 000 ms = 15 min
esphome:
name: ljh
friendly_name: LJH
esp32:
board: esp32dev
framework:
type: esp-idf
logger:
api:
encryption:
key: "1OCwTSndJs/8IwX/reO04WD3t6FW16xjrcxnScqiSG8="
ota:
- platform: esphome
password: "f12a8c146de656db334a794b85325e43"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Ljh Fallback Hotspot"
password: "JK9awEWfXFxR"
captive_portal:
i2c:
sda: 21
scl: 22
scan: true
id: bus_a
# =========================================================
# HÄLYTYKSET
# =========================================================
binary_sensor:
- platform: template
id: lisaapuut
name: "Lisää puuta pannuun"
- platform: template
id: anturi_vika
name: "Lämpötila-anturi vika"
# =========================================================
# GLOBAALIT
# =========================================================
globals:
- id: last_ok_time
type: unsigned long
restore_value: no
initial_value: '0'
# Nopea (fast) nousuntunnistus - checkpoint
- id: temp_fast_checkpoint
type: float
restore_value: no
initial_value: '0'
- id: temp_fast_checkpoint_time
type: unsigned long
restore_value: no
initial_value: '0'
# Hidas (slow) nousuntunnistus - checkpoint
- id: temp_slow_checkpoint
type: float
restore_value: no
initial_value: '0'
- id: temp_slow_checkpoint_time
type: unsigned long
restore_value: no
initial_value: '0'
- id: pump_until
type: unsigned long
restore_value: no
initial_value: '0'
- id: sensor_fault
type: bool
restore_value: no
initial_value: 'false'
- id: fault_recovery_time
type: unsigned long
restore_value: no
initial_value: '0'
# "Lisää puuta pannuun" -ilmoituksen ajastus:
# merkitsee ajanhetken, josta lähtien lämpötila on ollut
# jatkuvasti alle off_limit-rajan (ilman pumpun ajastinta)
- id: low_temp_since
type: unsigned long
restore_value: no
initial_value: '0'
# Laskevan trendin varhainen tunnistus - seuraa viimeisintä
# huippulukemaa (peak) ja verrataan siihen, kuinka paljon
# lämpötila on siitä pudonnut.
- id: temp_fall_checkpoint
type: float
restore_value: no
initial_value: '0'
- id: temp_fall_checkpoint_time
type: unsigned long
restore_value: no
initial_value: '0'
# Stagnaation (pysähtymisen) tunnistus - referenssiarvo, josta
# mitataan onko lämpötila pysynyt paikallaan riittävän kauan.
- id: temp_stagnation_checkpoint
type: float
restore_value: no
initial_value: '0'
- id: temp_stagnation_checkpoint_time
type: unsigned long
restore_value: no
initial_value: '0'
sensor:
- platform: bme680
i2c_id: bus_a
address: 0x77
update_interval: 10s
temperature:
id: bme_temp
name: "BME680 Lampotila"
on_value:
then:
- lambda: |-
const float ON_LIMIT = ${on_limit};
const float OFF_LIMIT = ${off_limit};
const float RISE_THRESHOLD_FAST = ${rise_threshold_fast};
const unsigned long RISE_WINDOW_FAST = ${rise_window_fast_ms};
const float RISE_THRESHOLD_SLOW = ${rise_threshold_slow};
const unsigned long RISE_WINDOW_SLOW = ${rise_window_slow_ms};
const unsigned long PUMP_RUNTIME = ${pump_runtime_ms};
const unsigned long RECOVERY_HOLD = ${recovery_hold_ms};
const unsigned long LOW_TEMP_ALERT_DELAY = ${low_temp_alert_delay_ms};
const float FALL_THRESHOLD = ${fall_threshold};
const unsigned long FALL_WINDOW = ${fall_window_ms};
const float STAGNATION_BAND = ${stagnation_band};
const unsigned long STAGNATION_WINDOW = ${stagnation_window_ms};
unsigned long now = millis();
// =====================================================
// 1. ANTURIN VALIDIOINTI
// =====================================================
bool valid = !(isnan(x) || x < -40 || x > 200);
if (!valid) {
id(sensor_fault) = true;
id(anturi_vika).publish_state(true);
id(P1).turn_on();
id(P2).turn_on();
return;
}
// =====================================================
// 2. PALAUTUMINEN
// =====================================================
if (id(sensor_fault)) {
id(sensor_fault) = false;
id(anturi_vika).publish_state(false);
id(fault_recovery_time) = now;
id(temp_fast_checkpoint) = x;
id(temp_fast_checkpoint_time) = now;
id(temp_slow_checkpoint) = x;
id(temp_slow_checkpoint_time) = now;
id(temp_fall_checkpoint) = x;
id(temp_fall_checkpoint_time) = now;
id(temp_stagnation_checkpoint) = x;
id(temp_stagnation_checkpoint_time) = now;
// vian aikana ei voida tietää oliko kylmä - nollataan
id(low_temp_since) = 0;
}
id(last_ok_time) = now;
// KORJAUS: julkaistaan anturi_vika-tila joka kierroksella,
// ei vain silloin kun se muuttuu. Aiemmin sensori jäi
// "unknown"-tilaan pysyvästi, jos vikaa ei koskaan
// tapahtunut - koska publish_state() ei tullut kutsutuksi
// kertaakaan ennen ensimmäistä vikaa tai palautumista.
id(anturi_vika).publish_state(false);
bool unsafe_period = (now - id(fault_recovery_time)) < RECOVERY_HOLD;
// =====================================================
// 3. LÄMPÖNOUSUN TUNNISTUS (JATKUVA, LIUKUVA IKKUNA)
//
// Nousu tarkistetaan JOKA mittauksella (ei vain kun
// ikkuna on täynnä). Näin pumppu käynnistyy heti kun
// kynnys ylittyy, vaikka se tapahtuisi nopeamminkin
// kuin asetettu ikkuna-aika.
//
// KORJAUS: checkpointia EI enää nollata nykyiseen
// arvoon pelkän ikkunan umpeutumisen takia. Se
// aiheutti "sahalaitabugin", jossa tasainen mutta
// hidas nousu (esim. juuri alle kynnyksen joka
// ikkunassa) ei koskaan päässyt kertymään, koska
// lähtötaso raahattiin jatkuvasti ylöspäin.
//
// Uusi sääntö: lähtötaso (checkpoint) siirretään
// eteenpäin VAIN kun löytyy uusi, matalampi pohja-
// lukema (todellinen paikallinen minimi), tai kun
// ikkuna umpeutuu EIKÄ noustu ollenkaan sitten
// viimeisimmän tarkistuksen. Näin nousu pääsee
// kertymään usean mittausvälin yli oikein.
// =====================================================
// --- Nopea tunnistus ---
if (id(temp_fast_checkpoint_time) == 0) {
id(temp_fast_checkpoint) = x;
id(temp_fast_checkpoint_time) = now;
} else {
float rise_fast = x - id(temp_fast_checkpoint);
if (rise_fast >= RISE_THRESHOLD_FAST) {
id(P2).turn_on();
id(pump_until) = now + PUMP_RUNTIME;
id(temp_fast_checkpoint) = x;
id(temp_fast_checkpoint_time) = now;
}
else if (x < id(temp_fast_checkpoint)) {
// uusi, matalampi pohjalukema -> siirretään lähtötasoa
id(temp_fast_checkpoint) = x;
id(temp_fast_checkpoint_time) = now;
}
else if (now - id(temp_fast_checkpoint_time) >= RISE_WINDOW_FAST) {
// ikkuna umpeutui eikä noussut riittävästi eikä uutta
// pohjaa löytynyt -> nollataan vasta nyt
id(temp_fast_checkpoint) = x;
id(temp_fast_checkpoint_time) = now;
}
}
// --- Hidas / herkkä tunnistus (esim. 0.3 astetta / 2 min) ---
if (id(temp_slow_checkpoint_time) == 0) {
id(temp_slow_checkpoint) = x;
id(temp_slow_checkpoint_time) = now;
} else {
float rise_slow = x - id(temp_slow_checkpoint);
if (rise_slow >= RISE_THRESHOLD_SLOW) {
id(P2).turn_on();
id(pump_until) = now + PUMP_RUNTIME;
id(temp_slow_checkpoint) = x;
id(temp_slow_checkpoint_time) = now;
}
else if (x < id(temp_slow_checkpoint)) {
// uusi, matalampi pohjalukema -> siirretään lähtötasoa
id(temp_slow_checkpoint) = x;
id(temp_slow_checkpoint_time) = now;
}
else if (now - id(temp_slow_checkpoint_time) >= RISE_WINDOW_SLOW) {
// ikkuna umpeutui eikä noussut riittävästi eikä uutta
// pohjaa löytynyt -> nollataan vasta nyt
id(temp_slow_checkpoint) = x;
id(temp_slow_checkpoint_time) = now;
}
}
// --- Laskevan trendin varhainen tunnistus (lisaapuut) ---
// Seurataan viimeisintä huippulukemaa (peak). Jos lämpötila
// on pudonnut siitä FALL_THRESHOLD verran FALL_WINDOW:n
// sisällä, annetaan "lisää puuta" -ilmoitus HETI, vaikka
// absoluuttinen lämpötila olisi vielä reilusti yli
// off_limit-rajan. Tämä antaa varoituksen jo silloin kun
// tuli alkaa hiipua, ei vasta kun se on jo sammunut.
bool early_fuel_warning = false;
if (id(temp_fall_checkpoint_time) == 0) {
id(temp_fall_checkpoint) = x;
id(temp_fall_checkpoint_time) = now;
} else {
float drop = id(temp_fall_checkpoint) - x;
if (drop >= FALL_THRESHOLD) {
early_fuel_warning = true;
id(temp_fall_checkpoint) = x;
id(temp_fall_checkpoint_time) = now;
}
else if (x > id(temp_fall_checkpoint)) {
// uusi huippulukema -> siirretään huippu ylemmäs
id(temp_fall_checkpoint) = x;
id(temp_fall_checkpoint_time) = now;
}
else if (now - id(temp_fall_checkpoint_time) >= FALL_WINDOW) {
// ikkuna umpeutui eikä pudonnut riittävästi eikä uutta
// huippua löytynyt -> nollataan vasta nyt
id(temp_fall_checkpoint) = x;
id(temp_fall_checkpoint_time) = now;
}
}
// --- Stagnaation (pysähtymisen) tunnistus ---
// Jos lämpötila pysyy STAGNATION_BAND:n sisällä
// referenssiarvosta, kello ei nollaudu - se kertoo
// kuinka kauan lämpötila on ollut käytännössä paikallaan.
// Heti kun poikkeama ylittää kaistan (nousu TAI lasku),
// referenssi ja kello nollautuvat, koska liikettä on
// taas havaittu.
if (id(temp_stagnation_checkpoint_time) == 0) {
id(temp_stagnation_checkpoint) = x;
id(temp_stagnation_checkpoint_time) = now;
} else if (fabs(x - id(temp_stagnation_checkpoint)) >= STAGNATION_BAND) {
id(temp_stagnation_checkpoint) = x;
id(temp_stagnation_checkpoint_time) = now;
}
bool stagnant = (now - id(temp_stagnation_checkpoint_time)) >= STAGNATION_WINDOW;
// =====================================================
// 4. AJASTIN
// =====================================================
if (id(pump_until) > 0 && now >= id(pump_until)) {
id(pump_until) = 0;
}
// =====================================================
// 5. PRIORITEETTILOGIIKKA (TÄRKEIN KORJAUS)
//
// HUOM: P2 (latauspumppu) on KRIITTINEN pumppu - se ei
// saa koskaan sammua vikatilanteessa. Tästä syystä
// sensor_fault-tarkistus on aina ensimmäinen ja siitä
// palataan (return) ennen kuin mikään myöhempi ehto
// pääsee sammuttamaan sen.
// =====================================================
// 1. KRIITTINEN FAILSAFE - P2 pysyy päällä, ei poikkeuksia
if (id(sensor_fault)) {
id(P2).turn_on();
return;
}
// 2. LÄMMITYS ON
if (x >= ON_LIMIT) {
id(P2).turn_on();
id(low_temp_since) = 0;
id(temp_fall_checkpoint) = x;
id(temp_fall_checkpoint_time) = now;
id(temp_stagnation_checkpoint) = x;
id(temp_stagnation_checkpoint_time) = now;
id(lisaapuut).publish_state(false);
return;
}
// 3. AJASTIN ON
if (id(pump_until) > 0) {
id(P2).turn_on();
id(low_temp_since) = 0;
id(temp_fall_checkpoint) = x;
id(temp_fall_checkpoint_time) = now;
id(temp_stagnation_checkpoint) = x;
id(temp_stagnation_checkpoint_time) = now;
id(lisaapuut).publish_state(false);
return;
}
// 4. OFF EHTO (AINOASTAAN VARMA TILA)
//
// Pumppu sammuu jos JOMPI KUMPI pätee:
// a) lämpötila on alle off_limit-rajan (klassinen ehto), TAI
// b) lämpötila on pysynyt käytännössä paikallaan
// (STAGNATION_BAND:n sisällä) yhtäjaksoisesti
// STAGNATION_WINDOW:n ajan - tulkitaan ettei lämpöä
// enää tule lisää, vaikka absoluuttinen lämpötila
// olisikin vielä yli off_limit-rajan.
if (!unsafe_period && (x < OFF_LIMIT || stagnant)) {
id(P2).turn_off();
}
// =====================================================
// 6. "LISÄÄ PUUTA PANNUUN" -ILMOITUS
//
// KORJAUS: hälytys sallitaan VAIN silloin kun latauspumppu
// P2 ON käynnissä. Jos P2 on pois päältä, hälytystä ei
// koskaan näytetä - riippumatta muista ehdoista alempana.
// (Aiemmin ehto oli päinvastoin: hälytys estyi kun P2 oli
// päällä, ja sallittiin kun P2 oli pois päältä.)
// =====================================================
if (!id(P2).state) {
id(lisaapuut).publish_state(false);
return;
}
// Kaksi laukaisutapaa, kumpi tahansa riittää:
//
// A) VARHAINEN: early_fuel_warning on true heti kun
// lämpötila on pudonnut FALL_THRESHOLD verran
// FALL_WINDOW:n sisällä (osiossa 3 laskettu) -
// reagoi jo hiipuvaan tuleen, ennen kuin lämpötila
// on edes lähelläkään off_limit-rajaa.
//
// B) VARMISTIN: jos lämpötila on pysynyt yhtäjaksoisesti
// alle off_limit-rajan LOW_TEMP_ALERT_DELAY:n ajan
// (esim. jos lasku on ollut niin tasainen/hidas ettei
// A koskaan laukea), ilmoitus annetaan silti.
//
// Ilmoitus nollautuu heti kun lämpötila nousee takaisin
// off_limit-rajan yli, tai kun ON_LIMIT/ajastin laukeaa
// (nollaukset tehty osioissa 2 ja 3 yllä).
// =====================================================
if (early_fuel_warning) {
id(lisaapuut).publish_state(true);
}
if (x < OFF_LIMIT) {
if (id(low_temp_since) == 0) {
id(low_temp_since) = now;
}
else if (now - id(low_temp_since) >= LOW_TEMP_ALERT_DELAY) {
id(lisaapuut).publish_state(true);
}
} else {
id(low_temp_since) = 0;
if (!early_fuel_warning) {
id(lisaapuut).publish_state(false);
}
}
pressure:
name: "BME680 Paine"
humidity:
name: "BME680 Kosteus"
gas_resistance:
name: "BME680 Kaasu"
# =========================================================
# ANTURIN VALVONTA
# =========================================================
interval:
- interval: 30s
then:
- lambda: |-
const unsigned long SENSOR_TIMEOUT = ${sensor_timeout_ms};
if (millis() - id(last_ok_time) > SENSOR_TIMEOUT) {
id(sensor_fault) = true;
id(anturi_vika).publish_state(true);
id(P1).turn_on();
id(P2).turn_on();
}
# =========================================================
# RELEET
#
# P1 = Pattereiden kiertovesi
# EI kriittinen. Ohjataan päälle turvatoimena vikatilanteissa
# (auttaa purkamaan lämpöä patteriverkostoon jos anturi vikaantuu).
#
# P2 = Energiatankin latauspumppu
# KRIITTINEN. Tämä EI SAA sammua vikatilanteessa tai bootin
# yhteydessä. restore_mode: ALWAYS_ON varmistaa, että pumppu on
# aina päällä heti käynnistyksen jälkeen, ennen kuin ensimmäinen
# kelvollinen lämpötilalukema on edes saatu (esim. sähkökatkon
# tai WiFi-ongelman jälkeen).
# =========================================================
switch:
- platform: gpio
id: P1
name: "Pattereiden kiertovesi"
pin: 25
restore_mode: ALWAYS_ON
- platform: gpio
id: P2
name: "Energiatankin latauspumppu"
pin: 26
restore_mode: ALWAYS_ON
Home Assistant ESP32 Growatt invertterin Modbus
Growatt MOD 8000TL3-HU (käytetty DIN asenteista ESP32 laitetta, jossa oma rele)
esphome:
name: solar
friendly_name: Solar
esp32:
variant: esp32s3
flash_size: 16MB
framework:
type: esp-idf
logger:
level: DEBUG
api:
encryption:
key: "WqbVi/yIvgpeu62sCdnbNCZ7S4IML6f4r1VwvlhviUA="
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Solar Fallback Hotspot"
password: "NHfyvtxKVdvN"
captive_portal:
# ============================================================
# WAVESHARE ESP32-S3-RELAY-1CH
# ============================================================
#
# RS485:
# GPIO17 = TX
# GPIO18 = RX
# GPIO21 = RS485 direction / flow control
#
# Relay:
# GPIO47 = Relay
#
# ============================================================
# ============================================================
# UART / RS485
# ============================================================
uart:
id: mod_uart
tx_pin: GPIO17
rx_pin: GPIO18
# Growatt MOD 8000TL3-HU
baud_rate: 9600
data_bits: 8
parity: NONE
stop_bits: 1
rx_buffer_size: 256
# ============================================================
# MODBUS
# ============================================================
modbus:
id: mod_bus
uart_id: mod_uart
# Waveshare ESP32-S3-Relay-1CH RS485 direction control
flow_control_pin: GPIO21
# send_wait_time = kuinka kauan odotetaan vastauksen alkua
# turnaround_time = tauko vastauksen jalkeen ennen seuraavaa komentoa
send_wait_time: 2s
turnaround_time: 1s
# ============================================================
# GROWATT MOD 8000TL3-HU
# ============================================================
#
# Rekisteriosoitteet:
# ESPHomessa kaytetaan raakaa input-rekisteriosoitetta.
# Esimerkiksi dokumentaation 33000 = ESPHomessa 3000.
#
# ============================================================
modbus_controller:
- id: growatt
# Default Growatt Modbus address
address: 0x01
modbus_id: mod_bus
setup_priority: -10
# Read every 5 seconds
update_interval: 5s
offline_skip_updates: 2
on_online:
then:
- logger.log: "Growatt Modbus ONLINE"
on_offline:
then:
- logger.log: "Growatt Modbus OFFLINE"
# ============================================================
# WAVESHARE RELAY
# ============================================================
switch:
- platform: gpio
name: "Solar Relay"
id: solar_relay
pin:
number: GPIO47
inverted: false
restore_mode: ALWAYS_OFF
# ============================================================
# TEST OUTPUT GPIO1
# ============================================================
- platform: gpio
name: "Solar Test GPIO1"
id: test_gpio1
pin:
number: GPIO1
inverted: false
restore_mode: ALWAYS_OFF
# ============================================================
# TEST OUTPUT GPIO2
# ============================================================
- platform: gpio
name: "Solar Test GPIO2"
id: test_gpio2
pin:
number: GPIO2
inverted: false
restore_mode: ALWAYS_OFF
# ============================================================
# GROWATT STATUS
# ============================================================
text_sensor:
- platform: template
name: "Growatt Inverter Status"
id: growatt_status_text
update_interval: 5s
lambda: |-
if (!id(growatt_status_code).has_state()) {
return {"Unknown"};
}
switch ((int) id(growatt_status_code).state) {
case 0:
return {"Waiting"};
case 1:
return {"Normal"};
case 3:
return {"Fault"};
default:
return {"Unknown"};
}
# ============================================================
# CONNECTION TEST
# ============================================================
- platform: template
name: "Growatt Modbus Connection"
id: growatt_modbus_connection
update_interval: 10s
lambda: |-
if (id(growatt_status_code).has_state()) {
return {"ONLINE - Modbus responds"};
}
return {"NO MODBUS RESPONSE"};
# ============================================================
# SENSORS
# ============================================================
sensor:
# ============================================================
# STATUS CODE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3000
name: "Growatt Status Code"
id: growatt_status_code
register_type: read
value_type: U_WORD
accuracy_decimals: 0
# ============================================================
# TOTAL PV POWER
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3001
name: "PV Input Power"
id: pv_input_power
register_type: read
value_type: U_DWORD
unit_of_measurement: "W"
device_class: power
state_class: measurement
filters:
- multiply: 0.1
# ============================================================
# PV1 VOLTAGE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3003
name: "PV1 Voltage"
register_type: read
value_type: U_WORD
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# PV1 CURRENT
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3004
name: "PV1 Current"
register_type: read
value_type: U_WORD
unit_of_measurement: "A"
device_class: current
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# PV1 POWER
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3005
name: "PV1 Power"
register_type: read
value_type: U_DWORD
unit_of_measurement: "W"
device_class: power
state_class: measurement
filters:
- multiply: 0.1
# ============================================================
# PV2 VOLTAGE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3007
name: "PV2 Voltage"
register_type: read
value_type: U_WORD
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# PV2 CURRENT
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3008
name: "PV2 Current"
register_type: read
value_type: U_WORD
unit_of_measurement: "A"
device_class: current
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# PV2 POWER
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3009
name: "PV2 Power"
register_type: read
value_type: U_DWORD
unit_of_measurement: "W"
device_class: power
state_class: measurement
filters:
- multiply: 0.1
# ============================================================
# AURINKOTUOTANTO
# ============================================================
#
# Growatt AC Output Power
#
# Hetkellinen aurinkotuotanto watteina.
#
# Home Assistant:
# sensor.solar_aurinkotuotanto
#
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3023
name: "Aurinkotuotanto"
id: solar_power
register_type: read
value_type: S_DWORD
unit_of_measurement: "W"
device_class: power
state_class: measurement
filters:
- multiply: 0.1
# ============================================================
# AC FREQUENCY
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3025
name: "AC Frequency"
register_type: read
value_type: U_WORD
unit_of_measurement: "Hz"
device_class: frequency
state_class: measurement
accuracy_decimals: 2
filters:
- multiply: 0.01
# ============================================================
# AC VOLTAGE L1
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3026
name: "AC Voltage L1"
register_type: read
value_type: U_WORD
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# AC CURRENT L1
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3027
name: "AC Current L1"
register_type: read
value_type: U_WORD
unit_of_measurement: "A"
device_class: current
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# AC POWER L1
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3028
name: "AC Power L1"
register_type: read
value_type: U_DWORD
unit_of_measurement: "VA"
device_class: apparent_power
state_class: measurement
filters:
- multiply: 0.1
# ============================================================
# AC VOLTAGE L2
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3030
name: "AC Voltage L2"
register_type: read
value_type: U_WORD
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# AC CURRENT L2
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3031
name: "AC Current L2"
register_type: read
value_type: U_WORD
unit_of_measurement: "A"
device_class: current
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# AC POWER L2
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3032
name: "AC Power L2"
register_type: read
value_type: U_DWORD
unit_of_measurement: "VA"
device_class: apparent_power
state_class: measurement
filters:
- multiply: 0.1
# ============================================================
# AC VOLTAGE L3
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3034
name: "AC Voltage L3"
register_type: read
value_type: U_WORD
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# AC CURRENT L3
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3035
name: "AC Current L3"
register_type: read
value_type: U_WORD
unit_of_measurement: "A"
device_class: current
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# AC POWER L3
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3036
name: "AC Power L3"
register_type: read
value_type: U_DWORD
unit_of_measurement: "VA"
device_class: apparent_power
state_class: measurement
filters:
- multiply: 0.1
# ============================================================
# LINE VOLTAGE L1-L2
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3038
name: "AC Voltage L1-L2"
register_type: read
value_type: U_WORD
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# LINE VOLTAGE L2-L3
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3039
name: "AC Voltage L2-L3"
register_type: read
value_type: U_WORD
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# LINE VOLTAGE L3-L1
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3040
name: "AC Voltage L3-L1"
register_type: read
value_type: U_WORD
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# OSTO VERKOSTA
# ============================================================
#
# Growatt AC Power To User
#
# Hetkellinen verkosta otettava teho watteina.
#
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3041
name: "Osto verkosta"
id: grid_import_power
register_type: read
value_type: U_DWORD
unit_of_measurement: "W"
device_class: power
state_class: measurement
filters:
- multiply: 0.1
# ============================================================
# VIENTI VERKKOON
# ============================================================
#
# Growatt AC Power To Grid
#
# Hetkellinen verkkoon syotettava teho watteina.
#
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3043
name: "Vienti verkkoon"
id: grid_export_power
register_type: read
value_type: U_DWORD
unit_of_measurement: "W"
device_class: power
state_class: measurement
filters:
- multiply: 0.1
# ============================================================
# KULUTUS JÄRJESTELMÄSSÄ
# ============================================================
#
# Growatt AC Power To Load
#
# Hetkellinen jarjestelman/kodin kulutus watteina.
#
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3045
name: "Kulutus järjestelmässä"
id: load_power
register_type: read
value_type: U_DWORD
unit_of_measurement: "W"
device_class: power
state_class: measurement
filters:
- multiply: 0.1
# ============================================================
# TOTAL OPERATING TIME
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3047
name: "Inverter Operating Time"
register_type: read
value_type: U_DWORD
unit_of_measurement: "s"
state_class: total_increasing
filters:
- multiply: 0.5
# ============================================================
# AC ENERGY TODAY
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3049
name: "AC Energy Today"
register_type: read
value_type: U_DWORD
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
filters:
- multiply: 0.1
# ============================================================
# TOTAL AC ENERGY
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3051
name: "AC Energy Lifetime"
register_type: read
value_type: U_DWORD
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
filters:
- multiply: 0.1
# ============================================================
# TOTAL PV ENERGY
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3053
name: "PV Energy Total"
register_type: read
value_type: U_DWORD
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
filters:
- multiply: 0.1
# ============================================================
# PV1 ENERGY TODAY
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3055
name: "PV1 Energy Today"
register_type: read
value_type: U_DWORD
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
filters:
- multiply: 0.1
# ============================================================
# PV1 ENERGY TOTAL
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3057
name: "PV1 Energy Total"
register_type: read
value_type: U_DWORD
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
filters:
- multiply: 0.1
# ============================================================
# PV2 ENERGY TODAY
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3059
name: "PV2 Energy Today"
register_type: read
value_type: U_DWORD
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
filters:
- multiply: 0.1
# ============================================================
# PV2 ENERGY TOTAL
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3061
name: "PV2 Energy Total"
register_type: read
value_type: U_DWORD
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
filters:
- multiply: 0.1
# ============================================================
# PV INSULATION
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3087
name: "PV Insulation"
register_type: read
value_type: U_WORD
unit_of_measurement: "kOhm"
accuracy_decimals: 0
# ============================================================
# INVERTER IPM TEMPERATURE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3093
name: "Inverter IPM Temperature"
register_type: read
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# INVERTER TEMPERATURE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3094
name: "Inverter Temperature"
register_type: read
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# BOOST TEMPERATURE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3095
name: "Boost Temperature"
register_type: read
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# COMMUNICATION BOARD TEMPERATURE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3097
name: "Communication Board Temperature"
register_type: read
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# P BUS VOLTAGE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3098
name: "P Bus Voltage"
register_type: read
value_type: U_WORD
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# N BUS VOLTAGE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3099
name: "N Bus Voltage"
register_type: read
value_type: U_WORD
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
accuracy_decimals: 1
filters:
- multiply: 0.1
# ============================================================
# POWER FACTOR
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3100
name: "Inverter Power Factor"
register_type: read
value_type: U_WORD
device_class: power_factor
accuracy_decimals: 2
# ============================================================
# OUTPUT POWER %
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3101
name: "Output Power Percent"
register_type: read
value_type: U_WORD
unit_of_measurement: "%"
accuracy_decimals: 0
# ============================================================
# MAX OUTPUT POWER LIMIT
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3102
name: "Output Power Limit"
register_type: read
value_type: U_DWORD
unit_of_measurement: "W"
filters:
- multiply: 0.1
# ============================================================
# FAULT CODE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3105
name: "Growatt Fault Code"
register_type: read
value_type: U_WORD
accuracy_decimals: 0
# ============================================================
# WARNING CODE
# ============================================================
- platform: modbus_controller
modbus_controller_id: growatt
address: 3106
name: "Growatt Warning Code"
register_type: read
value_type: U_WORD
accuracy_decimals: 0
# ============================================================
# HOME ASSISTANT ENERGY
# ============================================================
#
# Nämä muuttavat hetkellisen tehon (W) energiaksi (kWh).
#
# Home Assistant Energy Dashboard voi käyttää näitä:
#
# Aurinkotuotanto yhteensä
# Osto verkosta yhteensä
# Vienti verkkoon yhteensä
# Kulutus järjestelmässä yhteensä
#
# ============================================================
# ============================================================
# AURINKOTUOTANTO YHTEENSÄ
# ============================================================
- platform: integration
name: "Aurinkotuotanto yhteensä"
id: solar_energy_total
sensor: solar_power
time_unit: h
integration_method: trapezoid
restore: true
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
accuracy_decimals: 3
filters:
- multiply: 0.001
# ============================================================
# OSTO VERKOSTA YHTEENSÄ
# ============================================================
- platform: integration
name: "Osto verkosta yhteensä"
id: grid_import_energy
sensor: grid_import_power
time_unit: h
integration_method: trapezoid
restore: true
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
accuracy_decimals: 3
filters:
- multiply: 0.001
# ============================================================
# VIENTI VERKKOON YHTEENSÄ
# ============================================================
- platform: integration
name: "Vienti verkkoon yhteensä"
id: grid_export_energy
sensor: grid_export_power
time_unit: h
integration_method: trapezoid
restore: true
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
accuracy_decimals: 3
filters:
- multiply: 0.001
# ============================================================
# KULUTUS JÄRJESTELMÄSSÄ YHTEENSÄ
# ============================================================
- platform: integration
name: "Kulutus järjestelmässä yhteensä"
id: load_energy_total
sensor: load_power
time_unit: h
integration_method: trapezoid
restore: true
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
accuracy_decimals: 3
filters:
- multiply: 0.001
