community italiana di domotica personale
 
Creare un temporizzatore per sistemi clima su Home Assistant

Creare un temporizzatore per sistemi clima su Home Assistant

SCOPI DEL PROGETTO:
  • Creare un temporizzatore per pianificare l’attivazione di un termostato integrato con Home Assistant
  • Livello di difficoltàmedio/basso
  • Costo: nullo
CONCETTI AFFRONTATI:
  • Configurazione software
COMPONENTI SOFTWARE UTILIZZATE:
PREREQUISITI:
DISPOSITIVI FISICI UTILIZZATI:
GUIDA INDICATA A UTENTI CON ISTALLAZIONE:
Ambienti Home Assistant HassOS-Supervised-Core
NOTE E DISCLAIMER
  • qualsiasi eventuale modifica agli impianti domestici dev'essere progettata e realizzata SOLO da personale qualificato;
  • qualsiasi modifica non prevista attuata in proprio è a propria responsabilità personale nonché a proprio rischio e pericolo (i contenuti della presenta pagina hanno infatti puro scopo didattico) e fa decadere garanzia, omologazioni e certificazioni di qualità; dei dispositivi interessati;
  • tutte le tecniche descritte si intendono applicate a software e firmware aggiornati alle ultime versioni disponibili;
  • gli articoli di inDomus sono totalmente indipendenti e non sponsorizzati. Se mai questo cambiasse, verrà segnalato chiaramente sulle pagine oggetto di sponsorizzazione;
  • questa pagina è materialmente scritta e manutenuta da più individui: non ci si aspetti né si pretenda un supporto personale. In caso di difficoltà, chiedere supporto alla community sul nostro forum o sulla nostra chat;
  • se hai bisogno di orientarti, c'è la mappa.
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.

Termostato frontale
un termostato-temporizzatore.

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:


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.