Creiamo un accessorio per HomeKit

Feb 01, 2018 · 14 mins read · Costantino Pistagna · @valv0

Creiamo un accessorio per HomeKit

Quest’articolo vuole essere una breve guida introduttiva su come creare un accessorio compatibile con HomeKit sfruttando componentistica di riuso ed open source. Alla fine dell’articolo, se avrete seguito correttamente tutti i passi, potrete giocare con un telecomando per il vostro cancello automatico di casa comandabile ed azionabile con Siri / HomeKit. Come bonus, avrete la possibilità di aggiungere un sensore ambientale di umidità/temperatura.

Ingredienti:

  • 1x Raspberry PI3
  • 1x Arduino YUN (opzionale)
  • 1x Telecomando cancello automatico RF 433Mhz
  • 1x Transistor NPN
  • 1x Resistenza 2.2k
  • 1x Qualche cavo
  • 1x DHT22 (opzionale)
  • 5x Pazienza


Background

HomeKit è il protocollo di Apple a cui gli sviluppatori ed aziende che creano hardware e dispositivi per la domotica devono aderire se intendono essere compatibili con l’assistente vocale Siri e l’applicazione Home installati di default su tutti i nuovi dispositivi iOS.

HomeKit è un protocollo, ovvero una serie di regole e specifiche a cui i propri servizi devono aderire per potere essere integrati in maniera semplice e veloce con i dispositivi Apple. Il protocollo (nella versione developer no-profit) può essere scaricato e studiato liberamente a patto di accettare prima la licenza Apple annessa. Per maggiori informazioni è possibile andare qui:

Concettualmente, per potere creare qualcosa di funzionante (ed utile) con HomeKit è necessario creare due macro componenti che dialoghino tra di loro:

  • Un bridge o gateway che parla con il protocollo HomeKit e converte tutti i nostri segnali input / output analogici e digitali in caratteristiche esposte al protocollo HAP.
  • Una o più caratteristiche in grado di parlare con il server.

Tipicamente, le caratteristiche sono oggetti molto semplici ed elementari (lampadine, interruttori, sensori di temperatura, etc.). Per ragioni di costo e compattezza, dunque, risulta difficile potere implementare su di essi anche la logica di dialogo con il server.

La soluzione più comune che viene adottata dalla maggior parte dei produttori è quella di creare un ulteriore indirezione — denominata HUB — che permette di “raccogliere” più dispositivi elementari sotto un unico raccoglitore che poi si occupa ed ha la capacità logica di parlare con il server; la serie smart living di IKEA e quella di Philips funzionano con questo principio. Ne consegue che le caratteristiche sono più leggere ed economiche al prezzo di un ulteriore oggetto da aggiungere alla catena che in verità non è una grossa complicazione o problema, considerando il fatto che riduce il costo complessivo degli oggetti finali, sensibilmente.

Fig.1

Fortunatamente, per quanto riguarda il gateway è già presente da tempo una implementazione open parecchio stabile e modulare, basata su node e che adotta ed implementa tutte le funzionalità e specifiche richieste per creare un Gateway di accessori per HomeKit richieste dal protocollo HAP.

Il funzionamento è molto semplice. Attraverso un file di configurazione si dichiarano gli accessori supportati dal gateway. Questi accessori altro non sono che dei plugin software, rappresentanti particolari caratteristiche esposte. Il file di configurazione è un semplice file JSON e gli accessori sono degli oggetti JSON appartenenti ad un array. Alcuni parametri dei singoli accessori sono obbligatori, altri sono opzionali e dipendono dalle singole implementazioni, essendo dei parametri di inizializzazione specifici.

Implementazione — Gateway

Per prima cosa andremo a configurare il nostro gateway. Per questo compito ho deciso di usare un raspberry PI 3 su cui preventivamente avevo installato raspbian JESSIE:

Per installare homebridge, invece, vi basterà seguire le istruzioni riportate sulla pagina github del progetto. Io non ho riscontrato nessuna difficoltà.

Una volta completata l’installazione saremo in grado di lanciare il nostro gateway con il comando homebridge. Al primo avvio, il server ci avviserà del fatto che non sono configurati degli accessori e, dunque, l’utilità del gateway è davvero limitata.

Esiste una community molto attiva su npm ed, in pratica, si trova un plugin per quasi tutte le esigenze immaginabili. Nel nostro caso andremo a costruire un accessorio per aprire un cancello automatico, ossia per attuare un interruttore “stateless” di un telecomando RF. Aggiungeremo anche, se lo riteniamo opportuno, un sensore di umidità e temperatura che ci fornirà informazioni importanti (a costo praticamente zero) nella stanza in cui andremo a posizionare il nostro hub homekit.

Prima di passare alla costruzione dei nostri sensori ed alla configurazione del nostro HUB è necessario completare la configurazione del nostro gateway, aggiungendo due moduli in grado di parlare correttamente con i sensori sopra descritti:

una volta installati, saranno disponibili da subito. ci basterà configurare opportunamente il file config.json di homebridge.

{
  "bridge": {
    "name": "Home1bridge",
    "username": "CD:32:D2:E1:CC:33",
    "port": 50800,
    "pin": "031-43-153"
    },

  "description": "This is an example configuration file.",

  "accessories": [
    {
      "accessory": "HttpTemphum",
      "name": "Soggiorno",
      "url": "http://yuji.local/arduino/temp",
      "httpMethod": "GET",
      "humidity": true,
      "cacheExpiration": 60
    },
    {
      "accessory": "HTTP-SWITCH",
      "name": "Cancello",
      "switchType": "stateless",
      "onUrl": "http://yuji.local/arduino/switchOn"
    }
  ]
}

Al di la dei parametri banali quali nome e stanza, ogni modulo si aspetta di parlare con un indirizzo HTTP e ricevere determinate risposte per le operazioni richieste; ci basterà implementare questa logica semplice per completare il lavoro. Il gateway, infatti, si occuperà di tutto il resto per parlare correttamente con il protocollo Apple HAP.

Implementazione — HUB e sensoristica

Per costruire il nostro HUB che raggruppa e parla con i sensori, ho deciso di usare un vecchio arduino YUN che avevo comprato per un altro progetto e messo da parte in un cassetto. Tuttavia, se lo preferirete, potrete usare lo stesso raspberry che avete usato per costruire il gateway. Vi basterà riadattare i concetti di cui vi sto per parlare.

Il nostro HUB dovrà implementare un server http che risponda agli endpoint specificati nel file di configurazione di homebridge sopra, restituendo i valori estratti dai nostri sensori collegati ai PIN di input/output del microcontrollore di Arduino.

Prima di scrivere il codice per il nostro arduino, però, facciamo una pausa e dilettiamoci un pò di elettronica, costruendo quello che serve per trasformare un normale telecomando RF per cancelli automatici in un telecomando pilotato da Arduino.

Per prima cosa dovremo individuare i pin del nostro pulsante di apertura e saldargli due spezzoni di filo.

Fig.2

Nel frattempo avremo posizionato il nostro transitor N-P-N su una breadboard, opportunamente configurato con una resistenza da 2.2k sull’attuatore.

La base del transistor andrà collegata al pin 7 di arduino. L’emettitore, invece, andrà ad uno dei cavi che abbiamo appena saldato sul telecomando. Il collettore verrà collegato ad uno dei capi del pulsante del telecomando ed alla massa di arduino.

Fig.3

In questo modo, avremo creato un circuito normalmente aperto che si chiude (premendo di fatto il pulsante del telecomando) solo quando arriva un impulso di una certa soglia inviato dal pin digitale. Ci resta da codificare queste informazioni in un linguaggio comprensibile per il nostro microcontrollore.

Fig.4

Arduino YUN è una piattaforma ibrida molto interessante basata su un server linux, un modulo wifi ed un microcontrollore AT (del tutto simile a quello usato su arduino uno). Il pregio di Arduino, rispetto altri concorrenti, è quello di essere assolutamente semplice ed efficace nella gestione degli input/output analogico/digitali, offrendo un linguaggio di programmazione basato su C di rapida comprensione. Per poter eccitare il nostro pin 7 di cui sopra, ci basteranno poche righe di codice:

digitalWrite(7, HIGH);
delay(2000); 
digitalWrite(7, LOW);

a quanto sopra dobbiamo aggiungere la logica per il server HTTP. Arduino YUN include già una mini piattaforma HTTP server/client esposta in maniera molto semplice attraverso due oggetti di libreria denominati ClientBridge e ServerBridge. Il server bridge ci servirà per ascoltare le richieste provenienti dal mondo esterno ed il client per scrivere le nostre risposte a chi ci ha chiamato.

/*
  A simple HomeBridgeHub example for HomeBridge
  Author: Costantino Pistagna <costantino@sofapps.it>
*/

#include <dht.h>
#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>

dht DHT;

BridgeServer server;
String startString;

#define DHT22_PIN 7
#define REMOTEDOOR_PIN 4

void setup()
{
  pinMode(REMOTEDOOR_PIN, OUTPUT);
  digitalWrite(REMOTEDOOR_PIN, LOW);

  Bridge.begin();

  server.listenOnLocalhost();
  server.begin();
  Process startTime;
  startTime.runShellCommand("date");
  while (startTime.available()) {
    char c = startTime.read();
    startString += c;
  }
}



void loop()
{
  BridgeClient client = server.accept();
  if (client) {
    String command = client.readString();
    command.trim();       
//    Console.println(command);
    if (command == "temp") {
      int chk = DHT.read22(DHT22_PIN);
      switch (chk)
      {
        case DHTLIB_OK:
        client.print("{ \"temperature\":");
        client.print(DHT.temperature-2);
        client.print(", \"humidity\":");
        client.print(DHT.humidity);
        client.println("}");
        break;
        case DHTLIB_ERROR_CHECKSUM:
        client.println("{ \"status\" : \"Checksum error\"");
        break;
        case DHTLIB_ERROR_TIMEOUT:
        client.println("{ \"status\" : \"Timeout error\"");
        break;
        default:
        client.println("{ \"status\" : \"Unknown error\"");
        break;
      }
    }
    else if (command == "switchOn") {
      client.println("{\"status\" : \"OK\"}");
      digitalWrite(REMOTEDOOR_PIN, HIGH);
      delay(2000);      
      digitalWrite(REMOTEDOOR_PIN, LOW);
    }
    client.stop();
  }
  delay(50);
}

Resta da aggiungere il controllo di temperatura. Il sensore DHT22 è un sensore digitale ottimo per lo scopo: dal costo contenuto e dalla precisione digitale, non richiede taratura e può essere usato con una delle molte librerie per dispositivi a tecnologia DHT presenti.

  • il pin 1 è il pin di alimentazione
  • il pin 2 è il pin dove vengono modulati e serializzati i dati
  • il pin 3 è inusato
  • il pin 4 è la massa.

Fig.5

collegheremo il pin 2 al pin 4 del nostro arduino yun.

leggere la temperatura e l’umidità anche in questo caso è molto semplice:

int chk = DHT.read22(DHT22_PIN);
switch (chk)
{
    case DHTLIB_OK:
    client.print("{ \"temperature\":");
    client.print(DHT.temperature-2);
    client.print(", \"humidity\":");
    client.print(DHT.humidity);
    client.println("}");
    break;
    case DHTLIB_ERROR_CHECKSUM:
    client.println("{ \"status\" : \"Checksum error\"");
    break;
    case DHTLIB_ERROR_TIMEOUT:
    client.println("{ \"status\" : \"Timeout error\"");
    break;
    default:
    client.println("{ \"status\" : \"Unknown error\"");
    break;
}
Conclusioni — wrap it up

Bene. E’ il momento di mettere insieme tutti i pezzi. Una volta avviato lo sketch sul nostro Arduino, verifichiamo che tutti i comandi funzionino correttamente:

/temp

/switchOn

A questo punto ci basterà avviare homebridge e configurare opportunamente la nostra applicazione Home inserendo il qrcode che appare a schermo e seguendo i passi illustrati dall’app Home di Apple. Alla fine avremo qualcosa di questo tipo a schermo:

Fig.6

e la possibilità di parlare con il nostro amato dispositivo chiedendogli:

Che temperatura c’è a casa?

oppure ancora:

Apri il cancello

Considerazioni finali

homebridge è una piattaforma open molto flessibile che permette di dialogare con il protocollo HAP di Apple in maniera rapida ed efficace attraverso mini moduli e semplici tecnologie basate su http.

Costantino Pistagna
Costantino Pistagna · @valv0 Costantino is a software architect, project manager and consultant with more than ten years of experience in the software industry. He developed and managed projects for universities, medium-sized companies, multi-national corporations, and startups. He is among the first teachers for the Apple's iOS Developer Academy, based in Europe. Regularly, he lectures iOS development around the world, giving students the skills to develop their own high quality apps. While not writing apps, Costantino improves his chefs skills, travelling the world with his beautiful family.