You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
IoT-For-Beginners/translations/hr/2-farm/lessons/4-migrate-your-plant-to-the.../wio-terminal-connect-hub.md

12 KiB

Povežite svoj IoT uređaj s oblakom - Wio Terminal

U ovom dijelu lekcije povezat ćete svoj Wio Terminal s IoT Hubom kako biste slali telemetriju i primali naredbe.

Povežite svoj uređaj s IoT Hubom

Sljedeći korak je povezivanje vašeg uređaja s IoT Hubom.

Zadatak - povezivanje s IoT Hubom

  1. Otvorite projekt soil-moisture-sensor u VS Codeu.

  2. Otvorite datoteku platformio.ini. Uklonite ovisnost o biblioteci knolleary/PubSubClient. Ova biblioteka je korištena za povezivanje s javnim MQTT brokerom i nije potrebna za povezivanje s IoT Hubom.

  3. Dodajte sljedeće ovisnosti o bibliotekama:

    seeed-studio/Seeed Arduino RTC @ 2.0.0
    arduino-libraries/AzureIoTHub @ 1.6.0
    azure/AzureIoTUtility @ 1.6.1
    azure/AzureIoTProtocol_MQTT @ 1.6.0
    azure/AzureIoTProtocol_HTTP @ 1.6.0
    azure/AzureIoTSocket_WiFi @ 1.0.2
    

    Biblioteka Seeed Arduino RTC omogućuje interakciju s real-time satom u Wio Terminalu, koji se koristi za praćenje vremena. Preostale biblioteke omogućuju vašem IoT uređaju povezivanje s IoT Hubom.

  4. Dodajte sljedeće na dno datoteke platformio.ini:

    build_flags =
        -DDONT_USE_UPLOADTOBLOB
    

    Ovo postavlja zastavicu kompajlera koja je potrebna prilikom kompajliranja Arduino IoT Hub koda.

  5. Otvorite zaglavlje config.h. Uklonite sve MQTT postavke i dodajte sljedeću konstantu za connection string uređaja:

    // IoT Hub settings
    const char *CONNECTION_STRING = "<connection string>";
    

    Zamijenite <connection string> s connection stringom vašeg uređaja koji ste ranije kopirali.

  6. Povezivanje s IoT Hubom koristi token temeljen na vremenu. To znači da IoT uređaj mora znati trenutno vrijeme. Za razliku od operativnih sustava poput Windowsa, macOS-a ili Linuxa, mikrokontroleri ne sinkroniziraju automatski trenutno vrijeme putem Interneta. To znači da ćete morati dodati kod za dobivanje trenutnog vremena s NTP servera. Kada se vrijeme preuzme, može se pohraniti u real-time sat u Wio Terminalu, omogućujući kasnije dohvaćanje točnog vremena, pod uvjetom da uređaj ne izgubi napajanje. Dodajte novu datoteku pod nazivom ntp.h sa sljedećim kodom:

    #pragma once
    
    #include "DateTime.h"
    #include <time.h>
    #include "samd/NTPClientAz.h"
    #include <sys/time.h>
    
    static void initTime()
    {
        WiFiUDP _udp;
        time_t epochTime = (time_t)-1;
        NTPClientAz ntpClient;
    
        ntpClient.begin();
    
        while (true)
        {
            epochTime = ntpClient.getEpochTime("0.pool.ntp.org");
    
            if (epochTime == (time_t)-1)
            {
                Serial.println("Fetching NTP epoch time failed! Waiting 2 seconds to retry.");
                delay(2000);
            }
            else
            {
                Serial.print("Fetched NTP epoch time is: ");
    
                char buff[32];
                sprintf(buff, "%.f", difftime(epochTime, (time_t)0));
                Serial.println(buff);
                break;
            }
        }
    
        ntpClient.end();
    
        struct timeval tv;
        tv.tv_sec = epochTime;
        tv.tv_usec = 0;
    
        settimeofday(&tv, NULL);
    }
    

    Detalji ovog koda nisu obuhvaćeni ovom lekcijom. Definira funkciju initTime koja dohvaća trenutno vrijeme s NTP servera i koristi ga za postavljanje sata na Wio Terminalu.

  7. Otvorite datoteku main.cpp i uklonite sav MQTT kod, uključujući zaglavlje PubSubClient.h, deklaraciju varijable PubSubClient, metode reconnectMQTTClient i createMQTTClient, te sve pozive tim varijablama i metodama. Ova datoteka treba sadržavati samo kod za povezivanje s WiFi-jem, dobivanje vlažnosti tla i stvaranje JSON dokumenta s tim podacima.

  8. Dodajte sljedeće #include direktive na vrh datoteke main.cpp kako biste uključili zaglavlja za IoT Hub biblioteke i za postavljanje vremena:

    #include <AzureIoTHub.h>
    #include <AzureIoTProtocol_MQTT.h>
    #include <iothubtransportmqtt.h>
    #include "ntp.h"
    
  9. Dodajte sljedeći poziv na kraj funkcije setup za postavljanje trenutnog vremena:

    initTime();
    
  10. Dodajte sljedeću deklaraciju varijable na vrh datoteke, odmah ispod direktiva za uključivanje:

    IOTHUB_DEVICE_CLIENT_LL_HANDLE _device_ll_handle;
    

    Ovo deklarira IOTHUB_DEVICE_CLIENT_LL_HANDLE, ručku za povezivanje s IoT Hubom.

  11. Ispod toga dodajte sljedeći kod:

    static void connectionStatusCallback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void *user_context)
    {
        if (result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED)
        {
            Serial.println("The device client is connected to iothub");
        }
        else
        {
            Serial.println("The device client has been disconnected");
        }
    }
    

    Ovo deklarira callback funkciju koja će se pozvati kada se status veze s IoT Hubom promijeni, poput povezivanja ili prekida veze. Status se šalje na serijski port.

  12. Ispod toga dodajte funkciju za povezivanje s IoT Hubom:

    void connectIoTHub()
    {
        IoTHub_Init();
    
        _device_ll_handle = IoTHubDeviceClient_LL_CreateFromConnectionString(CONNECTION_STRING, MQTT_Protocol);
    
        if (_device_ll_handle == NULL)
        {
            Serial.println("Failure creating Iothub device. Hint: Check your connection string.");
            return;
        }
    
        IoTHubDeviceClient_LL_SetConnectionStatusCallback(_device_ll_handle, connectionStatusCallback, NULL);
    }
    

    Ovaj kod inicijalizira IoT Hub bibliotečki kod, zatim stvara vezu koristeći connection string u zaglavlju config.h. Ova veza temelji se na MQTT-u. Ako veza ne uspije, to se šalje na serijski port - ako to vidite u izlazu, provjerite connection string. Na kraju se postavlja callback za status veze.

  13. Pozovite ovu funkciju u funkciji setup ispod poziva initTime:

    connectIoTHub();
    
  14. Kao i kod MQTT klijenta, ovaj kod radi na jednom threadu pa treba vremena za obradu poruka koje hub šalje i prima. Dodajte sljedeće na vrh funkcije loop kako biste to omogućili:

    IoTHubDeviceClient_LL_DoWork(_device_ll_handle);
    
  15. Izgradite i učitajte ovaj kod. Vidjet ćete vezu u serijskom monitoru:

    Connecting to WiFi..
    Connected!
    Fetched NTP epoch time is: 1619983687
    Sending telemetry {"soil_moisture":391}
    The device client is connected to iothub
    

    U izlazu možete vidjeti kako se dohvaća NTP vrijeme, nakon čega se uređaj povezuje s IoT Hubom. Može proći nekoliko sekundi da se poveže, pa ćete možda vidjeti vlažnost tla u izlazu dok se uređaj povezuje.

    💁 UNIX vrijeme iz NTP-a možete pretvoriti u čitljiviji format koristeći web stranicu poput unixtimestamp.com

Slanje telemetrije

Sada kada je vaš uređaj povezan, možete slati telemetriju na IoT Hub umjesto na MQTT broker.

Zadatak - slanje telemetrije

  1. Dodajte sljedeću funkciju iznad funkcije setup:

    void sendTelemetry(const char *telemetry)
    {
        IOTHUB_MESSAGE_HANDLE message_handle = IoTHubMessage_CreateFromString(telemetry);
        IoTHubDeviceClient_LL_SendEventAsync(_device_ll_handle, message_handle, NULL, NULL);
        IoTHubMessage_Destroy(message_handle);
    }
    

    Ovaj kod stvara IoT Hub poruku iz stringa proslijeđenog kao parametar, šalje je na hub, a zatim čisti objekt poruke.

  2. Pozovite ovaj kod u funkciji loop, odmah nakon linije gdje se telemetrija šalje na serijski port:

    sendTelemetry(telemetry.c_str());
    

Obrada naredbi

Vaš uređaj treba obraditi naredbu s poslužiteljskog koda za upravljanje relejem. Ovo se šalje kao zahtjev za izravnu metodu.

Zadatak - obrada zahtjeva za izravnu metodu

  1. Dodajte sljedeći kod prije funkcije connectIoTHub:

    int directMethodCallback(const char *method_name, const unsigned char *payload, size_t size, unsigned char **response, size_t *response_size, void *userContextCallback)
    {
        Serial.printf("Direct method received %s\r\n", method_name);
    
        if (strcmp(method_name, "relay_on") == 0)
        {
            digitalWrite(PIN_WIRE_SCL, HIGH);
        }
        else if (strcmp(method_name, "relay_off") == 0)
        {
            digitalWrite(PIN_WIRE_SCL, LOW);
        }
    }
    

    Ovaj kod definira callback metodu koju IoT Hub biblioteka može pozvati kada primi zahtjev za izravnu metodu. Metoda koja se traži šalje se u parametru method_name. Ova funkcija ispisuje pozvanu metodu na serijski port, a zatim uključuje ili isključuje relej ovisno o nazivu metode.

    💁 Ovo bi se također moglo implementirati u jednoj izravnoj metodi, prosljeđujući željeno stanje releja u payloadu koji se može proslijediti sa zahtjevom metode i koji je dostupan iz parametra payload.

  2. Dodajte sljedeći kod na kraj funkcije directMethodCallback:

    char resultBuff[16];
    sprintf(resultBuff, "{\"Result\":\"\"}");
    *response_size = strlen(resultBuff);
    *response = (unsigned char *)malloc(*response_size);
    memcpy(*response, resultBuff, *response_size);
    
    return IOTHUB_CLIENT_OK;
    

    Zahtjevi za izravne metode trebaju odgovor, a odgovor se sastoji od dva dijela - odgovora kao teksta i povratnog koda. Ovaj kod stvara rezultat kao sljedeći JSON dokument:

    {
        "Result": ""
    }
    

    Ovo se zatim kopira u parametar response, a veličina ovog odgovora postavlja se u parametar response_size. Ovaj kod zatim vraća IOTHUB_CLIENT_OK kako bi pokazao da je metoda ispravno obrađena.

  3. Povežite callback dodavanjem sljedećeg na kraj funkcije connectIoTHub:

    IoTHubClient_LL_SetDeviceMethodCallback(_device_ll_handle, directMethodCallback, NULL);
    
  4. Funkcija loop će pozvati funkciju IoTHubDeviceClient_LL_DoWork za obradu događaja koje šalje IoT Hub. Ovo se poziva samo svakih 10 sekundi zbog delay, što znači da se izravne metode obrađuju samo svakih 10 sekundi. Kako bi ovo bilo učinkovitije, 10-sekundno kašnjenje može se implementirati kao mnogo kraćih kašnjenja, pozivajući IoTHubDeviceClient_LL_DoWork svaki put. Da biste to učinili, dodajte sljedeći kod iznad funkcije loop:

    void work_delay(int delay_time)
    {
        int current = 0;
        do
        {
            IoTHubDeviceClient_LL_DoWork(_device_ll_handle);
            delay(100);
            current += 100;
        } while (current < delay_time);
    }
    

    Ovaj kod će se ponavljati, pozivajući IoTHubDeviceClient_LL_DoWork i odgađajući za 100 ms svaki put. To će činiti onoliko puta koliko je potrebno da se odgodi za vrijeme dano u parametru delay_time. To znači da uređaj čeka najviše 100 ms za obradu zahtjeva za izravne metode.

  5. U funkciji loop, uklonite poziv IoTHubDeviceClient_LL_DoWork i zamijenite poziv delay(10000) sljedećim kako biste pozvali ovu novu funkciju:

    work_delay(10000);
    

💁 Ovaj kod možete pronaći u mapi code/wio-terminal.

😀 Vaš program za senzor vlažnosti tla povezan je s vašim IoT Hubom!


Odricanje od odgovornosti:
Ovaj dokument je preveden pomoću AI usluge za prevođenje Co-op Translator. Iako nastojimo osigurati točnost, imajte na umu da automatski prijevodi mogu sadržavati pogreške ili netočnosti. Izvorni dokument na izvornom jeziku treba smatrati autoritativnim izvorom. Za ključne informacije preporučuje se profesionalni prijevod od strane ljudskog prevoditelja. Ne preuzimamo odgovornost za bilo kakve nesporazume ili pogrešne interpretacije koje proizlaze iz korištenja ovog prijevoda.