Guide

PiGarden — Parte 5: Integrazione con Home Assistant (switch, timer, script e schedulazioni)

Questa è la quinta e ultima parte della serie PiGarden. Nella parte 4 abbiamo dato un cervello alla centralina; adesso la colleghiamo a Home Assistant, così l’irrigazione parte da sola e la comandi dal telefono. Vediamo lo stato delle zone, gli interruttori, i timer, gli script e le schedulazioni stagionali che irrigano il prato senza che io faccia nulla. L’indice della serie è in fondo.

Come parlano Home Assistant e la centralina

Home Assistant non ha bisogno di un’integrazione dedicata a piGarden: gli basta il broker MQTT e il ponte mqttconnector messo in piedi nella parte 4. Ricordi la bacheca dei biglietti? Qui se ne usano due, e basta:

  • pigarden/command — Home Assistant ci appende i comandi (open 1, close 1, close_all…) e la centralina li legge.
  • pigarden/result — piGarden ci appende lo stato in JSON: le zone, l’ultimo messaggio, la data dell’ultima pioggia.
Schema del flusso: il comando va da Home Assistant al broker MQTT, a mqttconnector e a piGarden; lo stato torna indietro sul topic pigarden/result
Il viaggio di un comando (in verde) e quello dello stato che torna indietro (in blu).

Quando accendi lo switch di una zona, il comando fa il giro del disegno da sinistra a destra e il relè scatta. Lo stato fa il percorso inverso: piGarden lo scrive su pigarden/result, Home Assistant lo legge e l’interruttore si mostra acceso. Se qualcosa non torna, hai due punti dove guardare: il biglietto del comando e quello dello stato.

Le entità che vedi qui sotto sono definite in file YAML. Il progetto piGarden offre anche un package pronto per Home Assistant, che puoi usare come punto di partenza (il link è nei riferimenti in fondo).

Attenzione

Se dopo una chiusura decisa dal Raspberry (un timer, la pioggia) la zona resta accesa in dashboard, quasi sicuramente è sbagliato MQTT_HOST in /etc/piGarden.conf: ne parlo nella parte 4. Lo stato di quelle chiusure lo pubblica piGarden stesso, non il ponte.

Spesso si incontra il proprio destino sulla strada che si intraprende per evitarlo.

Maestro Oogway

Leggere lo stato delle zone

Ogni messaggio su pigarden/result contiene lo stato di tutte le zone. Per ognuna creo un binary sensor MQTT, cioè un sensore a due stati, che vale «acceso» quando la valvola è aperta:

yaml
- name: pigarden_state_zona_1
  state_topic: "pigarden/result"
  payload_on: true
  payload_off: false
  value_template: "{{ value_json['zones']['1']['state'] in [1, 2] }}"
  device_class: running

Lo stesso blocco si ripete per le cinque zone, cambiando solo il numero. Oltre alle zone leggo dallo stesso topic l’ultimo messaggio di piGarden e la data dell’ultima pioggia, rilevata dal sensore e dal servizio meteo online:

yaml
- name: "piGarden Ultima Pioggia Sensore"
  unique_id: pigarden_last_rain_sensor
  state_topic: "pigarden/result"
  value_template: >
    {% if value_json['last_rain_sensor'] > "" and value_json['last_rain_sensor'] != "" %}
      {{ value_json['last_rain_sensor'] | int | timestamp_custom('%d/%m/%Y %H:%M', true) }}
    {% else %}
      sconosciuto
    {% endif %}

Un interruttore per ogni zona

Per comandare le valvole uso uno switch template. È un interruttore che non fa nulla da solo, ma ha due compiti: legge il proprio stato dal sensore di prima e, quando lo accendi o lo spegni, appende sulla bacheca il comando giusto.

yaml
- switch:
    - name: pigarden_zona_1
      unique_id: pigarden_zona_1
      state: "{{ is_state('binary_sensor.pigarden_state_zona_1', 'on') }}"
      turn_on:
        action: mqtt.publish
        data:
          topic: "pigarden/command"
          payload: >
            {% if is_state('input_boolean.pigarden_force_zona_1', 'off') %}
              open 1
            {% else %}
              open 1 force
            {% endif %}
      turn_off:
        action: mqtt.publish
        data:
          topic: "pigarden/command"
          payload: "close 1"

Se il sensore pioggia dice che è appena piovuto, piGarden rifiuta open 1: è il suo modo di non annaffiare sotto l’acqua. Per poter irrigare lo stesso, ogni zona ha un interruttore input_boolean.pigarden_force_zona_N («Forza irrigazione se piove»): quando è acceso, il comando diventa open 1 force, che scavalca il controllo.

Stop generale e riavvio

Tre script semplici, quelli che voglio sempre a portata di mano sulla dashboard: fermare tutto, fermare tutto e spegnere anche le schedulazioni, riavviare il Raspberry.

yaml
pigarden_close_all:
  alias: "piGarden — Stop tutte le zone"
  icon: mdi:stop-circle-outline
  sequence:
    - service: mqtt.publish
      data:
        topic: "pigarden/command"
        payload: "close_all"

pigarden_close_all_and_disable:
  alias: "piGarden — Stop e disabilita schedulazioni"
  icon: mdi:calendar-remove
  sequence:
    - service: mqtt.publish
      data:
        topic: "pigarden/command"
        payload: "close_all disable_scheduling"

pigarden_reboot:
  alias: "piGarden — Riavvia Raspberry"
  icon: mdi:restart
  sequence:
    - service: mqtt.publish
      data:
        topic: "pigarden/command"
        payload: "reboot"

Avviare una zona a tempo

Per un’irrigazione manuale di durata decisa al momento, ogni zona ha un input_number con i minuti (da 1 a 120) e uno script che lo legge quando lo lanci. Il comando giusto per un avvio a tempo è open_in, quello della parte 4: apre la zona dopo un certo numero di minuti (0 vuol dire subito) e la richiude dopo la durata indicata.

yaml
pigarden_timer_zona_1:
  name: "Timer Zona 1"
  min: 1
  max: 120
  step: 1
  unit_of_measurement: min
  icon: mdi:timer-outline
yaml
pigarden_run_zona_1:
  alias: "Avvia Zona 1 con timer variabile"
  variables:
    minuti: "{{ states('input_number.pigarden_timer_zona_1') | int }}"
    forza: "{{ states('input_boolean.pigarden_force_zona_1') }}"
  sequence:
    - service: mqtt.publish
      data:
        topic: "pigarden/command"
        payload: "{{ 'open_in 0 ' ~ minuti ~ ' 1' ~ (' force' if forza == 'on' else '') }}"
Attenzione

Un errore in cui sono caduto io. Per un po’ i miei script mandavano la forma sbagliata, open 1 600, con la durata in secondi dopo la zona. Il comando open accetta solo la zona e la parola force: la durata veniva ignorata, la valvola restava aperta finché non arrivava un close, e in più la durata prendeva il posto di force, che così non funzionava mai. Con open_in tutto torna.

Una nota sui tempi: la chiusura la fa una riga di cron che gira ogni minuto, quindi una zona a tempo resta aperta tra M e M+1 minuti. Provata con un timer di 1 minuto: 1 minuto e 23 secondi.

Le schedulazioni stagionali

L’irrigazione vera, quella che parte da sola all’alba, la governano le automazioni di Home Assistant. Le raggruppo per stagione, ognuna accesa da un interruttore (pigarden_crescita, pigarden_mantenimento, e in primavera pigarden_risemina). Il piano dipende dal prato e dal clima; il mio, per una festuca, è questo:

PeriodoGiorniDurata per zonaAvvio
Maggio – 15 giugnomar, gio, dom30 min05:30
16 – 30 giugnomar, gio, dom35 min05:30
Luglio – agostomar, gio, ven, dom40 min (zone 1-2), 55 min (zone 3-5)05:00
Settembremar, gio, dom25 min (zone 1-2), 33 min (zone 3-5)06:00

Le zone partono sempre nello stesso ordine: 1, 3, 5, 2, 4. Le zone 3, 4 e 5 hanno qualche minuto in più perché sotto passa un tubo di cemento che in estate scalda il terreno, e le do più acqua per compensare. L’orario è mattutino così il sole asciuga le foglie entro le nove-dieci, e questo riduce il rischio di funghi sulla festuca.

Linea del tempo di una mattina di luglio: le zone 1, 3, 5, 2 e 4 si susseguono dalle 5:00 alle 9:05
Una mattina di luglio o agosto: le cinque zone partono una dopo l'altra, senza mai sovrapporsi.

Ogni stagione è una coppia di automazioni, una che apre e una che chiude. Una sola automazione serve tutte le zone: ha un trigger per ogni orario e il comando da pubblicare viene scelto in base all’ora in cui scatta. Ecco la coppia di luglio e agosto, lato apertura:

yaml
- id: pigarden_mantenimento_apri
  alias: PiGarden Mantenimento — Apertura zone (Lug-Ago)
  trigger:
    - platform: time
      at: '05:00:00'
    - platform: time
      at: '05:40:00'
    - platform: time
      at: '06:35:00'
    - platform: time
      at: '07:30:00'
    - platform: time
      at: '08:10:00'
  condition:
    - condition: state
      entity_id: input_boolean.pigarden_mantenimento
      state: 'on'
    - condition: template
      value_template: "{{ now().month in [7, 8] }}"
    - condition: time
      weekday: [tue, thu, fri, sun]
  action:
    - service: mqtt.publish
      data:
        topic: pigarden/command
        payload: "{% set ora = now().strftime('%H:%M') %}{% if ora == '05:00' %}open 1{% elif ora == '05:40' %}open 3{% elif ora == '06:35' %}open 5{% elif ora == '07:30' %}open 2{% elif ora == '08:10' %}open 4{% endif %}"

L’automazione di chiusura è speculare: scatta agli orari in cui ogni zona deve finire (05:40, 06:35, 07:30, 08:10 e 09:05) e pubblica il close corrispondente. Qui uso ancora open e close a orari fissi, per scelta: le durate stanno negli orari, si leggono a colpo d’occhio e, se cambio il piano, modifico solo quelli.

Ogni stagione ha poi la sua automazione di spegnimento: per esempio una che il primo ottobre alle 00:01 spegne l’interruttore del mantenimento, così l’irrigazione si ferma da sola.

Attenzione

Non mettere la chiave initial: agli input_boolean delle stagioni. Forza il valore a ogni riavvio di Home Assistant: un interruttore che avevo spento restava acceso dopo un riavvio e riattivava una schedulazione fuori stagione. Senza initial: Home Assistant conserva lo stato reale.

Un messaggio quando serve

Il vecchio avviso generico («Irrigazione terminata») non diceva quale zona fosse finita, e quando finiva una zona sola era pure falso. Ora ricevo su Telegram un messaggio per ogni zona, con la durata (per esempio «Zona 5 (12 min)»). Ho aggiunto anche due allarmi, che parlano solo quando qualcosa non va:

  • zona non avviata: dopo un comando di apertura, Home Assistant aspetta 90 secondi che la zona risulti davvero aperta; se non lo è, avvisa e, quando può, dice perché (per esempio ha piovuto);
  • zona aperta troppo: scatta se una zona resta aperta oltre il timer impostato (minimo 10 minuti) più tre minuti.
Nota

Il messaggio di fine irrigazione l’ho provato con un ciclo vero. I due allarmi no: non ho ancora visto una zona rifiutata per pioggia né una rimasta aperta, e finché non capita non posso dirti che funzionino davvero.

La dashboard

Per comandare tutto da telefono ho una dashboard Lovelace nativa, senza iframe, su tre colonne (una sola su mobile). A sinistra il controllo generale: stop, ultima pioggia, meteo e i due interruttori stagionali. Al centro le cinque zone, ognuna con il suo switch, il timer, il flag «forza» e il pulsante di avvio a tempo. A destra la lista delle schedulazioni. Uso due card da HACS: button-card per i pulsanti e scheduler-card per la gestione degli orari.

Dashboard PiGarden in Home Assistant su tre colonne: a sinistra informazioni, ultima pioggia, meteo, pulsanti di stop e interruttori delle schedulazioni; al centro le zone con interruttore, timer, forza se piove e avvio con timer; a destra la card delle schedulazioni
La dashboard così com'è sul mio Home Assistant: controllo generale a sinistra, le zone al centro (qui se ne vedono tre su cinque), la lista delle schedulazioni a destra, ancora vuota.

Guardala da sinistra a destra. In alto a sinistra c’è l’ultimo messaggio di piGarden e la data dell’ultima pioggia; sotto il meteo, i due pulsanti di stop e i tre interruttori stagionali. Ogni scheda al centro è una zona: l’interruttore accende e spegne la valvola, il cursore sceglie i minuti, «Forza se piove» scavalca il controllo pioggia e «Avvia con timer» lancia lo script open_in della sezione precedente.

Con questo la serie è completa: dalla progettazione idraulica, ai componenti, alla centralina, al software, fino all’irrigazione automatica gestita da Home Assistant.

Riferimenti: lejubila.net/pigarden per il software open source e il package per Home Assistant

Scroll to Top