SCOPI DEL PROGETTO:
CONCETTI AFFRONTATI:
COMPONENTI SOFTWARE UTILIZZATE:
|
PREREQUISITI:
DISPOSITIVI FISICI UTILIZZATI:
|
GUIDA INDICATA A UTENTI CON ISTALLAZIONE: |
|
NOTE E DISCLAIMER
|
|
Revisione guida: 1.2 |
Abstract
Uno dei più grossi ed evidenti limiti del componente “Climate” – a quale fanno capo tutte le piattaforme dedicate all’integrazione di termostati e più genericamente di sistemi regolazione clima disponibili su Home Assistant – è l’assenza di uno scheduler, ovvero di un temporizzatore che permetta alle entità di questo tipo (sia dedicate alla gestione del riscaldamento che del raffrescamento) di accendersi/spegnersi non solo in relazione alla temperatura, ma anche a specifiche fasce orarie giornaliere/settimanali.
In attesa che Home Assistant si evolva in tal senso provvederemo allo scopo, tramite questo progetto, implementando il componete “Python Scripts“, il quale genera una o più entità di tipo azione a partire da script scritti in linguaggio Python. Tali script possono personalizzare il comportamento di Home Assistant: in questo caso li sfrutteremo, appunto, per creare un temporizzatore.
Per attivare l’entità “Climate” lo script proposto nel progetto utilizza una logica semplice, ovvero quella di variare la temperatura “target” del termostato in base al giorno e l’ora. Il comportamento del termostato, al variare della temperatura target, sarà ovviamente quello ordinario (attiva l’impianto in base al confronto con la temperatura dell’ambiente).
Creeremo quindi anche due entità “Input Number” atte alla “raccolta” di due temperature “target”:
- per impianti di riscaldamento, quella alta (target di riscaldamento ordinario) e quella di soglia bassa (temperatura minima da garantire sempre, a prescindere – a volte nota come “temperatura ECO”);
- per impianti di raffrescamento (condizionatori), quella di soglia alta (temperatura massima da garantire sempre, a prescindere) e quella bassa (target di raffreddamento ordinario).
Python Scripts
Come anticipato, il componente “Python Scripts” serve per definire delle entità che, se evocate (come azione), eseguano degli script scritti in Python.
Per attivare questo componente è necessario creare una cartella chiamata:
python_scripts/
all’interno della cartella principale di Home Assistant (su Raspberry Pi OS, “/home/homeassistant/.homeassistant“); in seguito, modificare la configurazione inserendo:
python_script:
e infine riavviare Home Assistant. Il riavvio dev’essere effettuato anche ad ogni eventuale aggiunta di script (sotto forma di file di testo con estensione “.py”) all’interno della cartella di cui sopra; al riavvio, una nuova entità chiamata “python_scripts.nomedelfile” apparirà nell’elenco delle azioni presenti su Home Assistant.
Assunti
Daremo per scontata l’esistenza di un’entità di tipo “Climate” chiamata “climate.termostato“, nonché della presenza di una lettura di temperatura ambientale, a scelta tra:
- l’attributo “temperature” dell’entità “climate.termostato“;
- un sensore “sensor.temperature“.
Alcune piattaforme di integrazione figlie del componente “Climate”, infatti, generano entità prive dell’attributo “temperature“, il che obbliga a censire il dato direttamente da un’altra entità.
Temperature target
Definiamo in configurazione due “Input Number” allo scopo di raccogliere da frontend le due temperature target:
input_number:
temp_high:
name: Target alto
min: 0
max: 30
step: 1
temp_low:
name: Target basso
min: 0
max: 30
step: 1
Le due entità (“input_number.temp_high” e “input_number.temp_low“) verranno utilizzate dallo script Python per valutare come regolare dinamicamente l’entità “climate.termostato“.
Script
Dopo aver attivato il componente “Python Script“, creiamo presso la cartella dedicata agli script un nuovo file chiamato “scheduler.py” contenente il seguente codice:
TEMP_HIGH = hass.states.get('input_number.temp_high')
TEMP_LOW = hass.states.get('input_number.temp_low')
climate_entity = 'climate.termostato' # definisce l'entità "Climate" da controllare
current_temp = hass.states.get(climate_entity).attributes['temperature']
# current_temp = float(hass.states.get('sensor.temperature'))
WEEK_SCHEDULE = [
[datetime.time( 0, 0), datetime.time( 1, 0)], # dalle 00:00 alle 01:00
[datetime.time( 7, 0), datetime.time( 9, 0)], # dalle 07:00 alle 09:00
[datetime.time(18, 0), datetime.time(23, 59, 59)] # dalle 18:00 alle 23:59
]
WEEKEND_SCHEDULE = [
[datetime.time( 0, 0), datetime.time( 2, 0)], # dalle 00:00 alle 01:00
[datetime.time(10, 0), datetime.time(13, 0)], # dalle 10:00 alle 13:00
[datetime.time(18, 0), datetime.time(23, 59, 59)] # dalle 18:00 alle 23:59
]
now = datetime.datetime.now().time()
if datetime.datetime.now().date().weekday() < 5:
current_schedule = WEEK_SCHEDULE
else:
current_schedule = WEEKEND_SCHEDULE
in_high_time = False
for high_time in current_schedule:
start = high_time[0]
end = high_time[1]
if start <= now <= end:
in_high_time = True
break
new_temp = TEMP_HIGH if in_high_time else TEMP_LOW
message = "Temperatura impostata a {} (era {})".format(new_temp.state, current_temp)
if str(new_temp.state) != str(current_temp):
# imposta la nuova temperatura sul termostato
hass.services.call('climate', 'set_temperature', {'entity_id': climate_entity, 'temperature': float(new_temp.state)})
# invio inoltre una notifica di sistema
hass.services.call('notify','notifications_send', {'title' : 'HA: Variazione al termostato', 'message': message})
Ricordarsi dunque di riavviare Home Assistant per generare l’entità “python_script.scheduler“.
Riavviare Home Assistant.
Analisi
Blocco iniziale
TEMP_HIGH = hass.states.get('input_number.temp_high')
TEMP_LOW = hass.states.get('input_number.temp_low')
climate_entity = 'climate.termostato' # definisce l'entità "Climate" da controllare
current_temp = hass.states.get(climate_entity).attributes['temperature']
# current_temp = float(hass.states.get('sensor.temperature'))
WEEK_SCHEDULE = [
[datetime.time( 0, 0), datetime.time( 1, 0)], # dalle 00:00 alle 01:00
[datetime.time( 7, 0), datetime.time( 9, 0)], # dalle 07:00 alle 09:00
[datetime.time(18, 0), datetime.time(23, 59, 59)] # dalle 18:00 alle 23:59
]
WEEKEND_SCHEDULE = [
[datetime.time( 0, 0), datetime.time( 2, 0)], # dalle 00:00 alle 01:00
[datetime.time(10, 0), datetime.time(13, 0)], # dalle 10:00 alle 13:00
[datetime.time(18, 0), datetime.time(23, 59, 59)] # dalle 18:00 alle 23:59
]
In questa prima parte si nota la raccolta dei valori dei due “Input Number” (“input_number.temp_high” e “input_number.temp_low“) presso due variabili ad hoc (“TEMP_HIGH” e “TEMP_LOW“) e altre due variabili, una contenente l’entity_id da controllare (“climate_entity“, in questo caso impostata a “climate.termostato“) e la temperatura ambientale attuale (“current_temp“) raccolta dallo stato del sensore “sensor.temperature“.
La riga commentata:
# current_temp = float(hass.states.get(‘sensor.temperature’))
è utile per quelle entità “Climate” che non espongano un dato reale della temperatura ambientale, ad esempio quelle prodotte tramite l’integrazione della testa termostatica “Eqiva eQ-3”. In questi casi – dato che il valore di lettura della temperatura è essenziale per il funzionamento del temporizzatore – basterà eliminare il # di commento (e commentare quella precedente) per far sì che la variabile (“current_temp“) venga valorizzata tramite il valore dello stato di un sensore di temperatura presente in configurazione (qui assunto come “sensor.temperature“).
Infine, il blocco di codice definisce gli orari settimanali di accensione (“WEEK_SCHEDULE“) e nel fine settimana (“WEEKEND_SCHEDULE“).
Ovviamente questo blocco è ampiamente personalizzabile sulla base delle proprie esigenze (specialmente il campo “climate_entity“).
BLOCCO OPERATIVO
È nella seconda parte che avviene tutta la magia:
now = datetime.datetime.now().time()
if datetime.datetime.now().date().weekday() < 5:
current_schedule = WEEK_SCHEDULE
else:
current_schedule = WEEKEND_SCHEDULE
in_high_time = False
for high_time in current_schedule:
start = high_time[0]
end = high_time[1]
if start <= now <= end:
in_high_time = True
break
new_temp = TEMP_HIGH if in_high_time else TEMP_LOW
message = "Temperatura impostata a {} (era {})".format(new_temp.state, current_temp)
if str(new_temp.state) != str(current_temp):
# imposta la nuova temperatura sul termostato
hass.services.call('climate', 'set_temperature', {'entity_id': climate_entity, 'temperature': float(new_temp.state)})
# invio inoltre una notifica di sistema
hass.services.call('notify','notifications_send', {'title' : 'HA: Variazione al termostato', 'message': message}
Lo script innanzitutto determina se sia un giorno settimanale o del weekend; poi verifica che ci si trovi in una delle fasce orarie impostate dall’utente: in caso ci si trovi in una fascia di accensione, imposta il valore della temperatura target dell’entità “Climate” (“climate.termostato“) alla temperatura “TEMP_HIGH“, altrimenti imposta “TEMP_LOW“.
Ovviamente questo è valido per un sistema di riscaldamento. In presenza di impianti di raffrescamento, modificare la riga:
new_temp = TEMP_HIGH if in_high_time else TEMP_LOW
in:
new_temp = TEMP_LOW if in_high_time else TEMP_HIGH
Automazione
A questo punto bisogna far sì che lo script venga eseguito ciclicamente.
Definiamo pertanto un’automazione di questo tipo:
automation:
- alias: 'Temporizzatore'
initial_state: True
trigger:
- platform: time
minutes: '/1' # ogni minuto
seconds: 00
- platform: homeassistant
event: start
condition: []
action:
action: python_script.scheduler
Così facendo, l’automazione evocherà lo script una volta al minuto (anche questo è personalizzabile), così da agire sul termostato in base alle regole impostate.
Il campo “condition” è stato lasciato volutamente vuoto; una personalizzazione aggiuntiva potrebbe essere quella di verificare (sfruttando il componente “Device Tracker“) l’effettiva presenza degli inquilini in casa, così da non agire sul sistema clima in assenza di quest’ultimi.
Considerazioni finali
Questo tipo di implementazione si sposa particolarmente bene con progetti e guide precedentemente pubblicate, tra i quali:
- Domotizzare un condizionatore tradizionale con Broadlink e Home Assistant
- Domotizzare il riscaldamento autonomo tramite Sonoff Basic e Home Assistant (senza un termostato fisico)
- Ottimizzare il riscaldamento autonomo con Home Assistant
- Domotizzare un termoventilatore da bagno con Broadlink e Home Assistant (laddove lo switch definito nel progetto venga poi applicato alla piattaforma “Generic Thermostat“ e affiancato a un sensore termico ambientale)
Questo progetto è ispirato al lavoro di Abílio Costa al quale va il ringraziamento della nostra community.
Domotizzare il riscaldamento autonomo tramite contatto pulito, Tasmota e Home Assistant
⚠️ Se di Home Assistant ne sai poco ma sei interessato a capirne di più, ti suggeriamo di partire da qui. |
Questa pagina è redatta, manutenuta e aggiornata dallo staff di inDomus, un gruppo di persone molto diverse tra loro che trovi, per domande e supporto, sul forum e sulla chat del sito. Alcuni link sono taggati in qualità di affiliati Amazon e riceviamo un compenso dagli acquisti idonei, utile al sostenimento del sito, ma le nostre recensioni sono tutte indipendenti e non sponsorizzate. Se ti sei perso, a tua disposizione c'è la mappa. |