Spájanie vecí

komunikačné technológie z pohľadu spotreby, dosahu komunikácie, množstva prenášaných dát, komunikačné protokoly používané v IoT, MQTT, M2M, sieťová konfigurácia ESP32, prepojenie so službami IFTTT a IBM Watson

Záznam z prednášky

Introduction

  • (slide) V prvej prednáške sme hovorili o architektúre IoT, kde sme si ukázali, ako svet IoT funguje v 4. vrstvách. Dnes sa však budeme rozprávať o komunikácii vo svete IoT, čo je téma charakteristická pre komunikáciu medzi zariadeniami prvej a druhej vrstvy. Zvyšné vrstvy sú už totiž prepojené vysokorýchlostným internetom, takže tam to už nie je žiadna výzva.

    IoT Architecture Overview [@s6]
  • (slide) Ak by sme mali začať hovoriť o komunikácii vecí v IoT, mali by sme začať s termínom M2M.

  • (slide) V skratke by sme M2M komunikáciu mohli charakterizovať ako priamu komunikáciu medzi dvoma zariadeniami pomocou akéhokoľvek komunikačného kanála bez nutnosti manuálnej ľudskej asistencie.

  • Hlavným účelom M2M komunikácie vo svete IoT je prenos dát od vecí (koncových zariadení) smerom do internetu. V tom prípade je jedným komunikujúcim zariadením samotný chytrý senzor a druhým komunikujúcim zariadením je počítačový systém, ktorý obyčajne tieto údaje posiela ďalej v rámci IoT architektúry.

  • Dá sa povedať, že M2M reprezentuje architektúru, kde nie je dôležité, aká technológia je použitá na prenos, prípadne pomocou akého komunikačného protokolu sú tieto údaje prenášané.

  • Nás však bude a musí zaujímať, aké technológie sú použité na prenos údajov (do internetu). Ich výber je samozrejme ovplyvnený viacerými faktormi:

    • cenou,
    • dosahom,
    • množstvom prenášaných dát, alebo
    • spotrebou.
  • Poďme sa teda pozrieť na niektoré technológie populárne v IoT bližšie.

Communication Technologies

Power Consumption

  • (slide) Jedným z dôležitých aspektov výberu komunikačnej technológie je jej spotreba. Treba si totiž uvedomiť, že častým riešením a nasadením IoT je v prostredí, kde nie je trvalý prívod elektrickej energie. Spotreba celého zariadenia (veci) teda predstavuje jeden z kľúčovch faktorov pri jeho dizajnovaní a návrhu.

    The Impact of Connectivity Technologies on the Power Consumption [@s24]

Communication Distance

  • (slide) Ďalším nemenej dôležitým aspektom výberu správnej komunikačnej technológie je jej dosah. Tu sa je možné odraziť od charakteristiky siete, v ktorej bude riešenie nasadené:

    • PAN (Personal Area Network)
    • LAN (Local Area Network)
    • MAN (Metropolitan Area Network)
    • WAN (Wide Area Network)
    • LPWAN (Low-Power Wide Area Network)
    Distance of Communication Technologies (zdroj)
  • (slide) Zjednodušene sa proste môžeme na dosah takto:

    • short range (< 10m) - nositeľná elektronika (PAN)
    • local area (< 100m) - domácnosť (LAN)
    • wide area (km) - celý zvyšok sveta (MAN, WAN, LPWAN)
    Communication Range Simplified [@s74]

Data Rate

  • V závislosti od charakteristiky prenášaných údajov nás môže zaujímať aj otázka max. množstva prenášaných dát. V tejto kategórii samozrejme dominujú technológie pre prenos dát v LAN sieťach (WiFi) a vo WAN sieťach (LTE, 2G, 3G, 4G).

Communication Protocols

  • (slide) V prípade technológií komunikujúcich v prostredí IP sietí nás bude zaujímať aj výber komunikačného protokolu, pomocou ktorého budú veci komunikovať buď so zariadeniami vyšších vrstviet (napr. posielať údaje zo senzorov) alebo medzi sebou navzájom.

    IoT Communicaton Protocols in ISO/OSI Model (zdroj)
  • Ako je možné vidieť, tak tieto protokoly pracujú na aplikačnej vrstve ISO/OSI modelu. Medzi tie najznámejšie a najpopulárnejšie protokoly patria:

    • HTTP
    • MQTT
    • CoAP
    • XMPP
    • LwM2M
  • (slide) My sa budeme venovať konkrétne len protokolom HTTP a MQTT.

    Most Popular IoT Protocols (zdroj)

Networking with ESP32

  • (slide) Ako sme sa rozprávali, mikrokontrolér ESP32 je vybavený WiFi modulom s podporou štandardu 802.11 b/g/n a so štandardnou podporou bezpečnostných vlastností IEEE 802.11 ako sú WFA, WPA/WPA2_ a WAPI.

  • Mikrokontrolér vie dokonca pracovať ako Access Point. Tým pádom môže poskytovať pre ostatné zariadenia v sieti rozličné služby. Napríklad môže slúžiť ako webový server, ktorý bude poskytovať webové používateľské rozhranie pre ovládanie pripojených akčných členov alebo môže poskytovať len stavovú stránku s informáciami zozbieranými z pripojených senzorov.

The network Module

  • (slide Pre prácu so sieťou má ESP32 k dispozícii modul network. Pred začiatkom práce ho teda importneme:

    >>> import network
  • Následne vytvoríme WiFi sieťové rozhranie, ktoré bude pracovať v režime pracovnej stanice (z angl. station interface) a aktivujeme ho:

    >>> wlan = network.WLAN(network.STA_IF)
    >>> wlan.active(True)
  • Následne sa môžeme pozrieť, aké bezdrôtové siete máme v dosahu:

    >>> wlan.scan()
  • Výsledkom bude zoznam sietí s informáciami ako:

    • SSID siete
    • MAC adresa rozhrania
    • sila signálu
    • číslo kanála
  • Ak sa teda chceme k niektorej z nich pripojiť, potrebujem poznať SSID siete a heslo pre prístup k nej. Samotné pripojenie vykonáme pomocou volania metódy .connect() nad objektom wlan:

    >>> wlan.connect('SSID', 'password')
  • Po (ne)úspešnom pripojení môžeme overiť stav pripojenia volaním metódy .isconnected(), ktorá vráti hodnotu True, ak sme sa úspešne pripojili alebo hodnotu False, ak nie. Nastavenie pripojenia vieme overiť volaním metódy .ifconfig():

    >>> wlan.isconnected()
    True
    >>> wlan.ifconfig()
    ('192.168.1.128', '255.255.255.0', '192.168.1.1', '192.168.1.1')
  • Len pre úplnosť je možné dodať, že MAC adresu zariadenia môžeme získať takto:

    >>> wlan.config('mac')
    b'`\x01\x94\x1b\xf7\xb1'
  • Od tohto momentu je mikrokontrolér pripojený a môžeme s ním vykonávať sieťové operácie.

Setting/Connecting to WiFi

  • Pripojiť sa k sieti je vhodné počas štartu zariadenia, resp. vzhľadom na šetrenie spotreby sa jemožné pripájať k sieti podľa potreby - napríklad v pravidelných intervaloch niekoľkokrát do dňa. Za tým účelom je možné použiť napr. túto funkciu:

    def do_connect(ssid, password):
        import network
        wlan = network.WLAN(network.STA_IF)
        wlan.active(True)
        if not wlan.isconnected():
            print('connecting to network...')
            wlan.connect(ssid, password)
            while not wlan.isconnected():
                pass
        print('network config:', wlan.ifconfig())

Home Automation with IFTTT

  • (slide) Pre jednoduchú ukážku sieťovej komunikácie si ukážeme pomocu služby IFTTT. Skratka IFTTT znamená If This Then That.

  • (slide) Podstatou tejto služby sú tzv. recepty. Princíp je jednoduchý - ak nastane udalosť, na ktorú sa viaže spúšťač (z angl. trigger), vykoná sa požadovaná akcia.

    IFTTT Recipe (zdroj)
  • Napr.:

    • If I am approaching my house, turn on the living room light, and start playing music.
    • If I exit my house, turn off all lights, and set the thermostat to 68 degrees.
    • If my plants are dry and they need to be watered, send me a text notification.
    • If my client who has Alzheimer’s, goes outside of a specific geographic location, send me a text message.
    • If I receive an email from my caregiver, send me a text message.
    • If I am on vacation at an exotic place, and I am taking photos there with my phone, upload them automatically to Facebook so my friends and family can see them too.
  • My túto službu použijeme ako jednoduchú notifikačnú službu. Samozrejme - fantázii sa medze nekladú a naozaj môže byť šikovným pomocníkom v oblasti domácej automatizácie. V tom prípade však potrebujete mať k dispozícii aj zariadenia, ktoré túto službu priamo podporujú.

  • Recept našej služby bude jednoduchý:

    ak sa doručí správa zo zariadenia (odmeranie teploty a vlhkosti v miestnosti), tak sa namerané hodnoty pošlú do kanála Notifications na Slack-u predmetu.

  • Na realizáciu použijeme senzor DHT11, ktorý vie odmerať teplotu aj vlhkosť.

Creating Service

  • Z menu používateľa vyberieme položku Create:

    IFTTT Create Service
  • Klikneme na slovo This, kde si vyberieme službu, ktorá bude definovať spúšťač (z angl. trigger). Zo zoznamu dostupných služieb si vyberieme Webhooks.

  • V službe Webhooks máme k dispozícii len spúšťač s názvom Receive a web request. Ten pracuje tak, že keď príde požiadavka na konkrétnu URL adresu, vykoná príslušnú akciu.

  • Po výbere spúšťača Receive a web request sa nás následne systém pýta na názov udalosti. Nazveme ju jednoducho update a spúšťač vytvoríme.

  • Následne klikneme na slovo That, kde máme možnosť vybrať službu, ktorá sa spustí po vyvolaní spúšťača. Vyhľadáme službu Slack.

  • Následne zo zoznamu vyberieme akciu, ktorá je v prípade služby Slack jediná a síce - poslať správu do príslušného kanála. V nasledujúcom okne vyberieme príslušný kanál a napíšeme kostru správy:

    The temperature in the room is °C and humidity is %.

    Ostatné položky môžeme zmazať a akciu vytvoríme.

  • Nakoniec už len potvrdíme vytvorené pravidlo, ktorému ešte môžeme upraviť nadpis. Pravidlo začne pracovať po kliknutí na tlačidlo Finish.

Testing Webhook Service

  • Keď sa vrátime na zoznam všetkých služieb klikneme na Webhooks. Na stránke klikneme na odkaz Documentation, ktorý zobrazí dokumentáciu opisujúcu spôsob použitia. Na stránke sa nachádza náš osobný kľúč, pomocou ktorého sa vieme autentifikovať pre použitie svojich vytvorených webhook-ov.

  • Na stránke si môžeme svoj webhook aj vyskúšať. Potrebujeme akurát poznať názov udalosti, ktorú chceme vyvolať. Tá je v našom prípade update. Tým dostaneme potrebnú URL adresu, kde môžeme poslať údaje zo senzora:

    https://maker.ifttt.com/trigger/update/with/key/API_KEY
  • Následne môžeme zadať aj hodnoty pre teplotu (value1) a pre vlhkosť (value2).

  • Po kliknutí na tlačidlo Test It budú údaje odoslané. Výsledok vieme skontrolovať v príslušnom kanáli Slack-u.

  • Súčasťou dokumentácie je aj ukážka použitia pomocou nástroja curl z príkazového riadku:

    curl -X POST -H "Content-Type: application/json" \
         -d '{"value1":"10","value2":"20"}' \
         https://maker.ifttt.com/trigger/update/with/key/API_KEY
  • Tým pádom máme k dispozícii všetky potrebné údaje na vyvolanie webhook-u z prostredia nášej veci v jazyku MicroPython.

Requesting Webhook from the Thing

  • (slide) V jazyku MicroPython na mikrokontroléri ESP32 použijeme modul urequests, ktorý je úpravou známeho modulu requests.

  • Za predpokladu, že je vec pripojená do internetu, môže vyzerať výsledné riešenie nasledovne:

    import urequests, ujson
    from machine import Pin
    from dht import DHT11
    from time import sleep
    
    url = 'https://maker.ifttt.com/trigger/update/with/key/API_KEY'
    sensor = DHT11(Pin(33))
    
    while True:
        # measure data from sensor
        sensor.measure()
        print(sensor.temperature(), sensor.humidity())
    
        # prepare data to send
        data = {
            'value1': sensor.temperature(), 
            'value2': sensor.humidity()
        }
        headers = {
            'Content-Type': 'application/json'
        }
    
        # send and close the response object
        response = urequests.post(url, headers=headers, json=data)
        response.close()
    
        sleep(10)

MQTT Protocol

  • (slide) MQTT je jeden z protokolov pre IoT.

MQTT and ESP32

  • (slide)

  • k dispozícii máme balík umqtt, ktorý je potrebné importnúť:

    from umqtt.robust import MQTTClient
  • vytvorenie objektu MQTTClient, resp. prihlásenie sa k MQTT brokerovi:

    client = MQTTClient('client-id', 'broker-ip', port)
    client.connect()

Sending Data to MQTT Broker

  • Následne môžeme správu odoslať pomocou metódy .publish():

    client.publish('messages', 'hello world')
  • Rozprávali sme sa o tom, že nepotrebujeme sa nutne pripájať často, resp. v tomto prípade byť pripojení neustále. V závislosti od použitia sa pripájať stačí napr. len pri odosielaní údajov. Kód teda môže vyzerať nasledovne:

    client.connect()
    client.publish('messages', 'hello world')
    client.disconnect()

Receiving Data from MQTT Broker

  • Ak chceme údaje prijímať, musíme vytvoriť callback, ktorý bude objekt MQTTClient volať, keď správu dostane:

    def on_message(topic, message):
        text = 'Message "{}" received in topic "{}"'
        print(text.format(topic, message))
  • Callback sa potom nastaví objektu MQTTClient pomocou volania metódy .set_callback():

    client = MQTTClient('client-id', 'broker-ip', port)
    client.set_callback(on_message)
  • Dôležité je, aby ste svojho klienta nezabudli prihlásiť do príslušnej témy (topic). To je však možné až potom, keď je klient pripojený k MQTT brokerovi:

    client.connect()
    client.subscribe('topic')
  • Následne sa môže začať vykonávať hlavná slučka našej veci. Poprípade môžeme explicitne volať metódu .wait_msg(), ak vyslovene čakáme na prijatie správy, čím sa zablokuje akékoveľvek ďalšie vykonávanie. Toto volanie je totiž blokujúce:

    print('Waiting for message...')
    client.wait_msg()  # blocking call

IBM Watson

  • (slide) komplexná platforma pre IoT riešenia od IBM

  • my si ukážeme jednoduchosť použitia v režime Quickstart

  • do formuláru na stránke zadáme len identifikátor nášho zariadenia (Device ID)

  • (slide) podpora pre IBM Watson IoT nie je na ESP32 natívna - je potrebné ju doinštalovať

    • balík sa volá micropython-watson-iot)

      • balíky pre Micropython je možné vyhľadať cez pypi
      • majú prefix micropython-*
    • doinštalovať niečo v Python-e je možné pomocou nástroja pip

    • v Micropython-e je možné ďalšie balíky doinštalovať tiež pomocou nástroja pip, ale vo forme príkazov samotného jazyka:

      import upip
      upip.install('micropython-watson-iot')
    • balíky sa inštalujú do priečinku lib/ priamo na ESP32

    • po nainštalovaní sú dostupné aj po reštarte ESP32

  • výhoda - je možné pripraviť kód tak, aby v prípade, že potrebné balíky neexistujú, tak sa najprv nainštalujú

  • (slide) po nainštalovaní je použitie podobné, ako v prípade MQTT:

    from watson_iot import Device
    
    device = Device(device_id='esp32-dht22',
                    device_type='my-device-type',
                    token='my-device-token')
    
    device.connect()
    data = {
        'degrees': 30.7, 
         'unit': 'C'
    }
    device.publishEvent('temperature', data)
    device.disconnect()
  • (slide) Výsledný kód bude vyzerať nasledovne:

    from dht import DHT11
    from machine import Pin
    from time import sleep
    from watson_iot import Device
    
    
    sensor = DHT11(Pin(23))
    
    device = Device(device_id='esp32-with-dht22',
                    device_type='type', token='token')
    
    while True:
        sensor.measure()
        data = {
            'degrees': sensor.temperature(),
            'unit': 'C'
        }
        device.connect()
        device.publishEvent('temperature', data)
        device.disconnect()
    
        sleep(10)