Sistemi di allarme senza fili. Home Assistant + MQTT

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 guidaInstallare 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 3 Modello B

Se volete già il Bundle:
I sistemi di allarme senza fili funzionano con componenti semplici. Partiamo con un semplice sensore di movimento:
L’arduino Wi-Fi, ESP8266 per comunicare senza fili con Home Assistant lo stato del sensore.

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:

allarme senza fili

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.

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:

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.

 

Se volete già il Bundle:

 

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:8123

switch_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 pdb

class 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.

6 commenti

  1. h0m3hassistant on

    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

  2. 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

  3. h0m3hassistant on

    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…

  4. 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

  5. Ciao, ho seguito la tua guida alla lettera, ahimè molte e molte volte, però non capisco dove sbaglio. quando attivo l’allarme “home away”, ogni trenta secondi mi arriva la notifica del sensore triggerato… tutti falsi allarmi. ho provato ad agire anche sui due regoli del sensore ma niente…..
    Qualche indicazione?

  6. Ciao Giuseppe,
    Se ti arriva sistematicamente ogni 30 secondi deve esserci qualche automazione o qualche riarmo da parte del sensore…E’ molto strano. Ti consiglio di controllare il file “Automations.yaml” per vedere che non ci siano automazioni che girano.

    Se imposti tutti gli stessi criteri di notifica ma con un altro sensore (umidità per esempio) funziona?

    Ciao

    Nik

Lascia un commento