Sistemi di allarme senza fili. Home Assistant + MQTT
Se siete capitati qui vuol dire che state cercando risposte alla domanda: Che tipi di sistemi di allarme senza fili ci sono in commercio? Beh, siete nel posto giusto.
In questo articolo andremo a vedere come è possibile configurare un allarme senza fili in completa autonomia sfruttando il potentissimo softwareHome Assistant.
Per chi non sa cos’è Home Assistant, consiglio la lettura di: Domotica con Home assistant. Il futuro per la casa domotica
Se siete curiosi di capire come funziona questo prodotto potete intanto provare ad installarlo nella vostra Raspberry con questa guida: Installare Home Assistant. Guida completa
Hai già dato un occhio all’indice di articoli inerenti la Domotica presenti nel mio sito? Facci un salto: Indice articoli di Domotica
L’occorrente per il nostro progetto “Allarme senza fili”:
La nostra fidatissima Raspberry Pi
1) Installazione e configurazione di Home Assistant.
Per configurare l’allarme senza fili, Il primo passo da fare è quello di preparare la vostra Raspberry ad ospitare il Home Assistant. Installare Home Assistant. Guida completa
Questo è quello che faremo oggi:
- Configurazione di Home Assistant
- Setup del nostro Arduino ESP8266
- Configurazione di Pushetta (App per le nostre notifiche)
- Configurazione di AppDaemon
Utilizzo del modulo di allarme senza fili di Home Assistant
Per il nostro progetto, andremo ad utilizzare il modulo di Home Assistant chiamato “Manual Alarm Control with MQTT Support”.
Che cos’è? La scelta è stata abbastanza forzata. Ho cercato e trovato un componente in grado di gestire l’armamento dell’allarme senza fili da remoto (Wi-Fi) e che cambi il suo status in base ad un input esterno (nel nostro caso il sensore di movimento).
Con questa meccanica, Home Assistant si occuperà di aggiornare lo stato del nostro allarme in base agli input forniti dal nostro sensore di movimento. Quando il sensore viene attivato, se l’allarme senza fili di Home Assistant è impostato su “Armato fuori casa” o “Armato in casa” riceveremo una notifica. Ovviamente la notifica può essere abbinata all’azionamento di una sirena.
2) Configurazione Home Assistant
La configurazione di Home Assistant è la seguente. Copiate questo dentro il file configuration.yaml
mqtt: broker: 127.0.0.1 port: 1883 client_id: home-assistant-1 username: VOSTRO_USERNAME password: VOSTRA_PASSWORD alarm_control_panel: - platform: manual_mqtt state_topic: "home/alarm/status" command_topic: "home/alarm/set/status" pending_time: 2 trigger_time: 10 sensor: - platform: mqtt state_topic: "sensor/motion1" name: "Motion Sensor 1" payload_on: "ON" payload_off: "OFF" device_class: motion notify: - name: pushettanotification platform: pushetta api_key: VOSTRA_API_KEY (Segue nel punto 5) channel_name: CHANNEL_NAME (Segue nel punto 5) automation: !include_dir_merge_list automations/
Se non avete configurato Mosquitto in Home Assistant, seguite questa guida: Domotica con Raspberry. Home Assistant + MQTT + Arduino. Fermatevi al punto 2.
Le informazioni in grassetto variano in base alla vostra configurazione.
- Create una cartella chiamata “automations” nello stesso path dove si trova il file configuration.yaml
- Create un file all’interno di questa cartella un file chiamato: “alarm_automation.yaml“
Copiate questo dentro il file “alarm_automation.yaml”
- alias: 'Alarm Away' trigger: - platform: state entity_id: sensor.motion_sensor_1 to: 'ON' condition: condition: state entity_id: alarm_control_panel.ha_alarm state: 'armed_away' action: - service: alarm_control_panel.alarm_trigger entity_id: alarm_control_panel.ha_alarm - service: notify.pushettanotification data_template: message: >- {%- for state in states.sensor if state.entity_id == trigger.entity_id -%} "{{ state.attributes.friendly_name }}" Allarme Triggerato {%- endfor -%} - service: light.turn_on entity_id: light.hue_white_lamp_2 - delay: seconds: 10 - service: light.turn_off entity_id: light.hue_white_lamp_2
Un riepilogo di quello che abbiamo configurato:
La prima parte ha predisposto Home Assistant con le configurazioni relative all’allarme, mqtt, sensore e notifiche.
La seconda parte ha creato un automatismo che, una volta ricevuto lo stato “ON” dal sensore di movimento, se l’allarme è impostato nello status “Alarm_Away”(Fuori casa), in sequenza fa:
- Scattare l’allarme senza fili mandandolo in status “Triggered“
- Manda una notifica al nostro cellulare tramite Pushetta
- Accende la luce Philips Hue per 10 secondi poi la spegne. (Quest’ultima automazione è a puro scopo illustrativo per simulare una sirena). Se non sai cosa sia una Philips Hue: Domotica con Raspberry: Phiilips Hue + Home Assistant.
- Rimuovete da “– service: light.turn_on” se non avete le Philips Hue
3) Configurazione Arduino ESP8266
Seguite il passo 4 della guida: Domotica con Raspberry. Home Assistant + MQTT + Arduino se non avete già configurato o installato il software per programmare l’Arduino. Per questa guida io ho usato il PIN 12 collegato al PIN del sensore. Gli altri 2 PIN sono Alimentazione e Massa.
Qualche info sul sensore:
I 2 Trimmer presenti nel sensore servono a:
- Aggiustare la sensibilità del sensore per essere attivato in determinate circostanze. (da 0 a 7 m)
- Tenere logicamente attivo il PIN d’uscita per un determinato periodo. (da 5s a 300s)
Questo invece è lo sketch da caricare nell’Arduino:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>const char* ssid = “VOSTRO_SSID”;
const char* password = “WIFI_PASSWORD”;
const char* mqtt_server = “IP_RASPBERRY”;
#define mqtt_user “MQTT_USERNAME”
#define mqtt_password “MQTT_PASSWORD”
#define sensor_topic “sensor/motion1”
int val = 0;
String stringVal = “OFF”;WiFiClient espClient;
PubSubClient client(espClient);void setup_wifi() {
delay(10);
Serial.println();
Serial.print(“Connecting to “);
Serial.println(ssid);WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}randomSeed(micros());
Serial.println(“”);
Serial.println(“WiFi connected”);
Serial.println(“IP address: “);
Serial.println(WiFi.localIP());
}void reconnect() {
while (!client.connected()) {
Serial.print(“Attempting MQTT connection…”);
if (client.connect(“ESP8266Client”, mqtt_user, mqtt_password)) {
Serial.println(“connected”);
client.subscribe(“home/alarm/set”);
} else {
Serial.print(“failed, rc=”);
Serial.print(client.state());
Serial.println(” try again in 5 seconds”);
delay(5000);
}
}
}void setup() {
//PIN UTILIZZATO PER IL SENSORE DI MOVIMENTO
pinMode(12, INPUT);
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
}void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();val = digitalRead(12);
//Serial.println(val);if (digitalRead(12) == HIGH) {
stringVal = “ON”;
Serial.println(“Il sensore è stato attivato”);
} else {
stringVal = “OFF”;
}client.publish(sensor_topic, String(stringVal).c_str(), true);
delay(1000);}
Questo Sketch in sintesi fa:
- Connette l’Arduino alla rete Wi-Fi
- Una volta connesso, si autentica al broker Mosquitto configurato su Home Assistant
- Ogni secondo, controlla lo stato del sensore, se viene attivato, aggiorna il suo stato notificandolo ad Home Assistant tramite l’ultima riga evidenziata.
Carichiamo il programma nell’Arduino e verifichiamo tramite la console SERIALE che il nostro sensore si attivi correttamente.
Fate particolare attenzione ai Topic utilizzati per il Broker MQTT. Devono essere sempre uguali.
4) Configurazione di Pushetta
Cos’è Pushetta? Pushetta è un’applicazione per Android e IOS in grado di mandare notifiche Push quando un device è registrato in uno specifico canale.
Iniziamo scaricando l’applicazione nel nostro telefono: Download Pushetta
Una volta scaricata andiamo nel sito ufficiale, registriamoci e creiamo un canale.
- Sito ufficiale: http://www.pushetta.com/
- Istruzioni funzionamento: http://www.pushetta.com/pushetta-docs/
Una volta registrati, create un canale con un nome personalizzato e segnatevi l’API KEY.
- Aggiornate il file configuration.yaml con i dati che avete appena ottenuto: CHANNEL_NAME e API_KEY. Queste info permetteranno ad Home Assistant di comunicare con Pushetta
- Installate l’applicazione nel telefono e inscrivetelo al CHANNEL che avete creato.
Consiglio di rendere il CHANNEL privato mediante il flag “Hidden” nella pagina dei CHANNELS. Fate una prova scrivendo un messaggio sulla destra per verificare se avete configurato tutto correttamente. Se tutto funziona dovreste ricevere una notifica nel vostro telefono.
5) Siamo pronti per testare
Una volta configurato tutto, riavviamo Home Assistant e verifichiamo il funzionamento!
- Nella schermata principale dovreste trovarvi un’icona con un campanello. Se la cliccate vi apre una finestra dove poter attivare e disattivare l’allarme senza fili:
- Se attiviamo il sensore di movimento con l’allarme senza fili in status “disarmed” non succede nulla. Se invece clicchiamo su “ARM AWAY” e attiviamo il sensore, se tutto è configurato bene, dovremmo ricevere quasi in tempo reale la notifica di Pushetta con il messaggio “Allarme Triggerato“!
Riflessioni
Mi fermo un secondo per fare delle considerazioni prima di proseguire. Se qualcuno di voi ha già provato a giocare con Home Assistant e nello specifico con il componente MQTT dell’allarme, avrà notato che se riavviamo il software o la Raspberry, l’allarme senza fili si resetta e si “Disarma”.
Onestamente quando parliamo di sistemi di allarme senza fili, se per una qualsiasi ragione deve riavviarsi la Raspberry, si disattiva, non me ne faccio nulla.
Come risolvere questa cosa? Ho dovuto spremermi parecchio ma alla fine, grazie all’aiuto della comunità di Home Assistant ho trovato una soluzione fenomenale.
Sfruttando Appdaemon (Vedremo più avanti come usarlo per una fichissima Dashboard da muro), è possibile tenere traccia di tutti gli status di cui abbiamo bisogno e, se dovessimo riavviare la Raspberry, possiamo ripristinarli automaticamente.
6) Installazione e configurazione di Appdaemon + Fix Status Allarme senza fili
Connettiamoci in SSH alla nostra Raspberry.
- Installiamo AppDaemon
sudo pip3 install appdaemon
- Creiamo e compiliamo il file di configurazione dentro: /home/homeassistant/conf/appdaemon.yaml
AppDaemon:
logfile: STDOUT
errorfile: STDERR
logsize: 100000
log_generations: 3
threads: 10
cert_verify: True
time_zone: <time zone>
api_port: 5000
HASS:
ha_url: http://IP_RASPBERRY:8123switch_reset:
module: switch_reset
class: SwitchReset
file: /home/pi/preserved_states
delay: 0
additional_entities: alarm_control_panel.ha_alarm
- Aggiornate i permessi dei gruppi in /etc/group modificando e sostituendo queste 2 righe:
pi:x:1000:homeassistant
homeassistant:x:995:pi
- Create una cartella chiamata “apps” dentro /home/homeassistant/conf/ e create dentro il file: “switch_reset.py”
Copiate il contenuto dentro questo file:
import appdaemon.appapi as appapi
import shelve
import time
import pdbclass SwitchReset(appapi.AppDaemon):
def initialize(self):
self.listen_event(self.ha_event, “ha_started”)
self.listen_event(self.appd_event, “appd_started”)
self.listen_state(self.state_change, “input_boolean”)
self.listen_state(self.state_change, “input_select”)
self.listen_state(self.state_change, “input_slider”)
if “additional_entities” in self.args:
self.additional_entities = [x.strip() for x in self.args[“additional_entities”].split(“,”)]for entity in self.additional_entities:
self.listen_state(self.state_change, entity)def ha_event(self, event_name, data, kwargs):
self.log_notify(“Home Assistant restart detected”)
self.run_in(self.set_switches, self.args[“delay”])def appd_event(self, event_name, data, kwargs):
self.log_notify(“AppDaemon restart detected”)
self.run_in(self.set_switches, self.args[“delay”])def state_change(self, entity, attribute, old, new, kwargs):
dev_db = shelve.open(self.args[“file”])
type, id = entity.split(“.”)if type == “climate”:
climate_dict = { ‘temperature’: self.get_state(entity, ‘temperature’), ‘operation_mode’: self.get_state(entity, ‘operation_mode’) }
if dev_db[entity] != climate_dict:
dev_db[entity] = climate_dict
self.log_notify(“State change: {} to {}”.format(entity, climate_dict))
else:
dev_db[entity] = new
self.log_notify(“State change: {} to {}”.format(entity, new))dev_db.close()
def set_switches(self, kwargs):
dev_db = shelve.open(self.args[“file”])
self.log_notify(“Setting switches”)
state = self.get_state()
for entity in state:
type, id = entity.split(“.”)
if type == “input_boolean” or type == “input_select” or type == “input_slider” or (entity in self.additional_entities):
if entity in dev_db:
if type != “climate”:
if dev_db[entity] != state[entity][“state”]:
self.log_notify(“Setting {} to {} (was {})”.format(entity, dev_db[entity], state[entity][“state”]))
new_state = self.set_state(entity, state = dev_db[entity])
else:
temp = self.get_state(entity, “temperature”)
mode = self.get_state(entity, “operation_mode”)if dev_db[entity][“temperature”] != temp:
self.log_notify(“Setting {} to {} (was {})”.format(entity, dev_db[entity], temp))
new_state = self.call_service(“climate/set_temperature”, temperature = dev_db[entity][“temperature”], entity_id = entity)
if dev_db[entity][“operation_mode”] != mode:
self.log_notify(“Setting {} to {} (was {})”.format(entity, dev_db[entity], temp))
new_state = self.call_service(“climate/set_operation_mode”, operation_mode = dev_db[entity][“operation_mode”], entity_id = entity)
else:
self.log_notify(“Adding {}, setting value to current state ({})”.format(entity, state[entity][“state”]))
if type != “climate”:
dev_db[entity] = state[entity][“state”]
else:
dev_db[entity] = self.get_state(entity, “temperature”)dev_db.close()
def log_notify(self, message, level = “INFO”):
if “log” in self.args:
self.log(message)
if “notify” in self.args:
self.notify(message, “ios”, name=”ios”)
- Posizioniamoci nella cartella di Home Assistant e sistemiamo i permessi
cd /home/homeassistant/
sudo chown -R homeassistant.homeassistant .
- Avviamo AppDaemon tramite il comando:
appdaemon -c /home/homeassistant/conf
Se abbiamo configurato tutto correttamente dovremmo vedere qualcosa di simile a questo:
appdaemon -c /home/homeassistant/conf
2016-08-22 10:08:16,575 INFO Got initial state
2016-08-22 10:08:16,576 INFO Loading Module: /home/homeassistant/conf/apps/hello.py
2016-08-22 10:08:16,578 INFO Loading Object hello_world using class HelloWorld from module hello
2016-08-22 10:08:16,580 INFO Hello from AppDaemon
2016-08-22 10:08:16,584 INFO You are now ready to run Apps!
Una volta avviato AppDaemon, se ora proviamo ad armare l’allarme e riavviare la Raspberry o Home Assistant, l’allarme senza fili che abbiamo configurato ritornerà al suo stato precedente. Ora si che ragioniamo!
Per maggiori informazioni su AppDaemon e su come configurare l’avvio automatico del servizio fate riferimento a questo Installazione e configurazione di AppDaemon
Considerazioni finali sui sistemi di allarme senza fili
Come avete visto, Home Assistant è in grado di soddisfare qualsiasi tipo di esigenza. Prossimamente vedremo come poter utilizzare Home Assistant per altri progetti!
Ovviamente questo esempio di allarme è solo l’inizio. L’idea è quella di avere la casa tappezzata di sensori-ESP8266 connessi in WI-Fi che scambiano in continuazione informazioni con Home Assistant.
4 commenti
Ciao Master,
L’indentazione del file non ha importanza, puoi copiarlo così com’è. E’ la prima volta che vedo quell’errore. Bisognerebbe fare un po’ di troubleshooting. Ti consiglio di provare a postarlo anche nel Forum di Home Assistant e vedere se qualcuno l’ha mai avuto in passato
Ciao
Nik
purtroppo ho solo switch non MQTT, dunque cercavo un sistema per salvare gli stati da mantenere dopo il riavvio.
Ho provato ma configurando l’app switch_reset.py ho il seguente errore di Appdaeon:
Jan 12 20:11:44 raspberrypi appdaemon[14377]: File “/usr/local/lib/python3.5/dist-packages/appdaemon/appdaemon.py”, line 901, in read_app
Jan 12 20:11:44 raspberrypi appdaemon[14377]: conf.modules[module_name] = importlib.import_module(module_name)
Jan 12 20:11:44 raspberrypi appdaemon[14377]: File “/usr/lib/python3.5/importlib/__init__.py”, line 121, in import_module
Jan 12 20:11:44 raspberrypi appdaemon[14377]: raise TypeError(msg.format(name))
Jan 12 20:11:44 raspberrypi appdaemon[14377]: TypeError: the ‘package’ argument is required to perform a relative import for ‘._switch_reset’
l’indentazione del file /home/homeassistant/conf/appdaemon.yaml come sarebbe? anche se credo l’errore sia da qualche altra parte…
Ciao,
Tecnicamente quello che dici è corretto. Puoi utilizzare Appdaemon per monitorare gli status degli switches. Tuttavia però, dato che è una funzionalità integrata del protocollo MQTT, puoi utilizzare il flag “Retain”. Se usi Switch MQTT, puoi utilizzare quel Flag per far tenere lo status ai tuoi switch.
Maggiori info qui: https://home-assistant.io/components/switch.mqtt/
Alla prossima
Nik
Ciao, una domanda:
nel caso non avessi l’allarme senza fili, ma seguissi la guida dal passo 6, potrei comunque beneficiare del mantenimento di stato sui vari switch e sensori in seguito al riavvio di homeassistant?
naturalmente senza includere ‘additional_entities: alarm_control_panel.ha_alarm’ nel file di configurazione
Grazie