# మీ IoT డివైస్‌ను క్లౌడ్‌కు కనెక్ట్ చేయండి - Wio Terminal ఈ పాఠంలోని ఈ భాగంలో, మీరు మీ Wio Terminalను మీ IoT హబ్‌కు కనెక్ట్ చేసి, టెలిమెట్రీ పంపటానికి మరియు ఆదేశాలను అందుకోవడానికి ఉపయోగిస్తారు. ## మీ డివైస్‌ను IoT హబ్‌కు కనెక్ట్ చేయండి తరువాతి దశలో మీ డివైస్‌ను IoT హబ్‌కు కనెక్ట్ చేయాలి. ### పని - IoT హబ్‌కు కనెక్ట్ చేయండి 1. VS కోడ్‌లో `soil-moisture-sensor` ప్రాజెక్ట్‌ను తెరవండి 1. `platformio.ini` ఫైల్‌ను తెరవండి. `knolleary/PubSubClient` లైబ్రరీ డిపెండెన్సీని తీసివేయండి. ఇది పబ్లిక్ MQTT బ్రోకర్‌కు కనెక్ట్ కావడానికి ఉపయోగించబడింది, కానీ IoT హబ్‌కు కనెక్ట్ కావడానికి అవసరం లేదు. 1. క్రింది లైబ్రరీ డిపెండెన్సీలను జోడించండి: ```ini 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 ``` `Seeed Arduino RTC` లైబ్రరీ Wio Terminalలో రియల్-టైం క్లాక్‌తో ఇంటరాక్ట్ కావడానికి కోడ్ అందిస్తుంది, ఇది సమయాన్ని ట్రాక్ చేయడంలో ఉపయోగపడుతుంది. మిగతా లైబ్రరీలు మీ IoT డివైస్‌ను IoT హబ్‌కు కనెక్ట్ అవ్వడానికి అనుమతిస్తాయి. 1. `platformio.ini` ఫైల్ బాటమ్‌లో క్రింది కోడ్ జోడించండి: ```ini build_flags = -DDONT_USE_UPLOADTOBLOB ``` ఇది ఆర్డ్యూనో IoT హబ్ కో드를 కంపైల్ చేసే సమయంలో అవసరమైన కంపైలర్ ఫ్లాగ్‌ను సెటప్ చేస్తుంది. 1. `config.h` హెడ్డర్ ఫైల్‌ను తెరవండి. అన్ని MQTT సెట్టింగులను తీసివేసి, డివైస్ కనక్షన్ స్ట్రింగ్ కోసం క్రింది కాన్స్టెంట్‌ను జోడించండి: ```cpp // IoT హబ్ సెట్టింగులు const char *CONNECTION_STRING = ""; ``` క్రమంలో పంపిన `` స్థానాన్ని మీ డివైస్ కనెక్షన్ స్ట్రింగ్‌తో మార్చండి. 1. IoT హబ్ కనెక్షన్ సమయాత్మక టోకెన్ ఉపయోగిస్తుంది. దీని అర్థం, IoT డివైస్ ప్రస్తుతం సమయాన్ని తెలుసుకోవాలి. Windows, macOS లేదా Linux వంటి ఆపరేటింగ్ సిస్టమ్స్ లాగా, మైక్రోకంట్రోల్లర్లు ఇంటర్నెట్ ద్వారా సమయాన్ని ఆటోమేటిక్‌గా సింక్రొనైజ్ చేయవు. కాబట్టి మీరు [NTP](https://wikipedia.org/wiki/Network_Time_Protocol) సర్వర్ నుండి సమయాన్ని పొందడానికి కోడ్ జోడించాలి. సమయం పొందిన తర్వాత, అది Wio Terminalలో రియల్-టైం క్లాక్‌లో నిల్వ చేయబడుతుంది, ఇది పవర్ కోల్పోకుండా ఉన్నప్పుడు తర్వాత సరిగా సమయాన్ని రిక్వెస్ట్ చేయగలుగుతుంది. క్రింది కోడ్‌తో `ntp.h` అనే కొత్త ఫైల్‌ను జోడించండి: ```cpp #pragma once #include "DateTime.h" #include #include "samd/NTPClientAz.h" #include 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); } ``` ఈ కోడ్ వివరాలు ఈ పాఠం వెనుకగా ఉన్నాయి. ఇది `initTime` అనే ఫంక్షన్‌ను నిర్వచిస్తుందని, ఇది NTP సర్వర్ నుంచి ప్రస్తుతం సమయాన్ని పొందుతుంది మరియు Wio Terminalలో క్లాక్‌ను సెట్ చేస్తుంది. 1. `main.cpp` ఫైల్‌ను తెరిచి, MQTT కోడును మొత్తం తొలగించండి, ఇందులో `PubSubClient.h` హెడ్డర్ ఫైల్, `PubSubClient` వేరియబుల్ డిక్లరేషన్, `reconnectMQTTClient` మరియు `createMQTTClient` మెథడ్స్, మరియు వాటికి సంబంధించిన ఇతర కాల్స్ కూడా ఉన్నాయి. ఈ ఫైల్ WiFiకి కనెక్ట్ అయ్యే, మట్టి తేమను పొందే మరియు దానిని JSON డాక్యుమెంట్‌లో సృష్టించే కోడ్ మాత్రమే ఉండాలి. 1. `main.cpp` ఫైల్ టాప్‌లో క్రింది `#include` డైరెక్టివ్స్ జోడించి, IoT హబ్ లైబ్రరీలు మరియు సమయాన్ని సెటప్ చేసే హెడ్డర్ ఫైళ్లను చేర్చండి: ```cpp #include #include #include #include "ntp.h" ``` 1. `setup` ఫంక్షన్ చివర క్రింది కాల్‌ను జోడించి, ప్రస్తుతం సమయాన్ని సెట్ చేయండి: ```cpp initTime(); ``` 1. ఫైల్ టాప్‌లో, `#include` డైరెక్టివ్స్ వెంట క్రింది వేరియబుల్ డిక్లరేషన్‌ను జోడించండి: ```cpp IOTHUB_DEVICE_CLIENT_LL_HANDLE _device_ll_handle; ``` ఇది `IOTHUB_DEVICE_CLIENT_LL_HANDLE` అనే హ్యాండిల్ డిక్లేర్ చేస్తుంది, ఇది IoT హబ్ కనెక్షన్‌కు ఉపయోగపడుతుంది. 1. దాని కింద క్రింది కోడ్ జోడించండి: ```cpp 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"); } } ``` ఇది ఒక కాల్‌బ్యాక్ ఫంక్షన్‌ను డిక్లేర్ చేస్తుంది, ఇది IoT హబ్ కనెక్షన్ స్థితి మారినప్పుడు (కనెక్ట్/డిస్కనెక్ట్) పిలువబడుతుంది. ఈ స్థితి సీరియల్ పోర్ట్‌కు పంపబడుతుంది. 1. అదనంగా, IoT హబ్‌కు కనెక్ట్ అయ్యే ఫంక్షన్ జోడించండి: ```cpp 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); } ``` ఈ కోడ్ IoT హబ్ లైబ్రరీని ప్రారంభించి, `config.h` ఫైల్‌లో ఉన్న కనెక్షన్ స్ట్రింగ్ ఉపయోగించి కనెక్షన్ సృష్టిస్తుంది. ఈ కనెక్షన్ MQTT ఆధారితంగా ఉంటుంది. కనెక్షన్ విఫలమైతే, ఆ అవస్థ సీరియల్ పోర్ట్‌కు పంపబడుతుంది - అవుట్‌పుట్‌లో ఇది కనిపిస్తే కనెక్షన్ స్ట్రింగ్‌ని తనిఖీ చేయండి. చివరగా కనెక్షన్ స్టేటస్ కాల్‌బ్యాక్ సెటప్ చేస్తుంది. 1. ఈ ఫంక్షన్‌ను `setup` ఫంక్షన్ లో `initTime` కాల్ తర్వాత పిలవండి: ```cpp connectIoTHub(); ``` 1. MQTT క్లయింట్ లాగా, ఈ కోడ్ సింగిల్ త్రెడ్‌లో నడుస్తుంది కాబట్టి హబ్ పంపే మరియు హబ్ చేరుకునే సందేశాలను ప్రాసెస్ చేయడానికి సమయం అవసరం. ఈ కోసం `loop` ఫంక్షన్ టాప్‌లో క్రింది కోడ్ జోడించండి: ```cpp IoTHubDeviceClient_LL_DoWork(_device_ll_handle); ``` 1. ఈ కోడ్‌ని బిల్డ్ చేసి అప్‌లోడ్ చేయండి. సీరియల్ మానిటర్‌లో కనెక్షన్ కనబడుతుంది: ```output Connecting to WiFi.. Connected! Fetched NTP epoch time is: 1619983687 Sending telemetry {"soil_moisture":391} The device client is connected to iothub ``` అవుట్‌పుట్‌లో మీరు NTP సమయం తీసుకున్నారని, ఆ తర్వాత డివైస్ క్లయింట్ కనెక్ట్ అవుతున్నట్లు చూడవచ్చు. కనెక్ట్ కావడానికి కొన్ని సెకన్లు పట్టవచ్చు, కనుక డివైస్ కనెక్ట్ అయివున్నప్పుడు కూడా మట్టి తేమ అవుట్‌పుట్‌లో కనిపించవచ్చు. > 💁 మీరు UNIX సమయాన్ని మరింత చదవదగిన రూపంలోకి మార్చడానికి [unixtimestamp.com](https://www.unixtimestamp.com) వంటి వెబ్‌సైట్‌ను ఉపయోగించవచ్చు ## టెలిమెట్రీ పంపండి మీ డివైస్ కనెక్ట్ అయిన తర్వాత, మీరు MQTT బ్రోకర్‌కు బదులు IoT హబ్‌కు టెలిమెట్రీ పంపవచ్చు. ### పని - టెలిమెట్రీ పంపు 1. `setup` ఫంక్షన్ కంటే ముందు క్రింది ఫంక్షన్ జోడించండి: ```cpp 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); } ``` ఈ కోడ్ స్ట్రింగ్ రూపంలో వచ్చిన డేటాను IoT హబ్ సందేశంగా సృష్టించి, హబ్‌కు పంపడమే, తరువాత సందేశ ఆబ్జెక్టును క్లియర్ చేస్తుంది. 1. ఈ కోడ్‌ను `loop` ఫంక్షన్‌లో, టెలిమెట్రీ సీరియల్ పోర్టుకు పంపిన తర్వాతి లైనులో పిలవండి: ```cpp sendTelemetry(telemetry.c_str()); ``` ## ఆదేశాలను హ్యాండిల్ చేయండి మీ డివైస్ సర్వర్ కోడ్ నుంచి రీలే నిర్వహణకు సంబంధించిన ఆదేశాన్ని హ్యాండిల్ చేయాలి. ఇది డైరెక్ట్ మెథడ్ రిక్వెస్ట్ రూపంలో పంపబడుతుంది. ## పని - డైరెక్ట్ మెథడ్ రిక్వెస్ట్‌ని హ్యాండిల్ చేయండి 1. `connectIoTHub` ఫంక్షన్ ముందు క్రింది కోడ్ జోడించండి: ```cpp 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); } } ``` ఈ కోడ్ IoT హబ్ లైబ్రరీ డైరెక్ట్ మెథడ్ రిక్వెస్ట్ అందుకున్నప్పుడు పిలవగల కాల్‌బ్యాక్ మెథడ్‌ను నిర్వచిస్తుంది. పిలవబడిన మెథడ్ పేరు `method_name` ప్యారామీటర్‌లో వస్తుంది. ఈ ఫంక్షన్ మెథడ్ పేరును సీరియల్ పోర్టుకు ప్రింట్ చేసి, ఆ మెథడ్ పేరు ఆధారంగా రీలేని ఆన్ లేదా ఆఫ్ చేస్తుంది. > 💁 ఇది ఒకే డైరెక్ట్ మెథడ్ రిక్వెస్ట్‌లో కూడా అమలు చేయవచ్చు, అనుకున్న రీలే స్థితిని మెథడ్ రిక్వెస్ట్‌తో పాటు అందించే పేలొడ్ ద్వారా పంపించి, `payload` ప్యారామీటర్ ద్వారా అందుబాటులో చేయవచ్చు. 1. `directMethodCallback` ఫంక్షన్ ముగింపులో క్రింది కోడ్ జోడించండి: ```cpp 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; ``` డైరెక్ట్ మెథడ్ రిక్వెస్ట్‌కి స్పందన అవసరం, ఇది రెండు భాగాలుగా ఉంటుంది - పాఠ్య స్పందన మరియు రీటర్న్ కోడ్. ఈ కోడ్ క్రింది JSON డాక్యుమెంట్ ఫార్మాట్‌లో ఫలితాన్ని సృష్టిస్తుంది: ```JSON { "Result": "" } ``` దీనిని `response` ప్యారామీటర్‌లో కాపీ చేసి, స్పందన పరిమాణాన్ని `response_size` ప్యారామీటర్‌లో సెట్చేస్తుంది. ఆపై ఈ కోడ్ `IOTHUB_CLIENT_OK` తిరిగి ఇస్తుంది, తద్వారా మెథడ్ సరిగ్గా నిర్వహించబడిందని సూచిస్తుంది. 1. ఈ కాల్‌బ్యాక్‌ను కింది కోడ్‌ను `connectIoTHub` ఫంక్షన్ ముగింపులో జోడించి కनेक్ట్ చేయండి: ```cpp IoTHubClient_LL_SetDeviceMethodCallback(_device_ll_handle, directMethodCallback, NULL); ``` 1. `loop` ఫంక్షన్, IoT హబ్ పంపే ఈవెంట్స్‌ని ప్రాసెస్ చేయటానికి `IoTHubDeviceClient_LL_DoWork` ఫంక్షన్‌ను పిలుస్తుంది. ఇది ప్రతి 10 సెకన్లకు మాత్రమే పిలవబడుతుంది కారణం `delay` కారణంగా, అంటే డైరెక్ట్ మెథడ్స్ కూడా ప్రతి 10 సెకన్లకు ఒకసారి ప్రాసెస్ అవుతాయి. దీన్ని మరింత సమర్థవంతంగా మార్చడానికి, 10 సెకన్ల డిలేను చిన్న చిన్న డిలే లుగా చేయవచ్చు, ప్రతి సారి `IoTHubDeviceClient_LL_DoWork` పిలవబడుతుంది. దీన్ని చేయడానికి, `loop` ఫంక్షన్ ముందు క్రింది కోడ్ జోడించండి: ```cpp void work_delay(int delay_time) { int current = 0; do { IoTHubDeviceClient_LL_DoWork(_device_ll_handle); delay(100); current += 100; } while (current < delay_time); } ``` ఈ కోడ్ ఆవృతంగా `IoTHubDeviceClient_LL_DoWork` పిలుస్తూ, ప్రతి సారి 100ms డిలే చేస్తుంది. ఇది `delay_time` ప్యారామీటర్‌లో ఇచ్చిన సమయం వరకు ఈ ప్రక్రియను చేస్తుంది. దీని అర్థం, డివైస్ డైరెక్ట్ మెథడ్ రిక్వెస్ట్‌లను అత్యధికంగా 100ms లోపు ప్రాసెస్ చేయడానికి వేచి ఉంటుంది. 1. `loop` ఫంక్షన్‌లో, `IoTHubDeviceClient_LL_DoWork` కాల్‌ను తీసివేసి, `delay(10000)` ని ఈ క్రింది కొత్త ఫంక్షన్ కాల్‌తో మార్చండి: ```cpp work_delay(10000); ``` > 💁 మీరు ఈ కోడ్‌ను [code/wio-terminal](../../../../../2-farm/lessons/4-migrate-your-plant-to-the-cloud/code/wio-terminal) ఫోల్డర్‌లో చూడవచ్చు. 😀 మీ మట్టి తేమ సెన్సార్ ప్రోగ్రామ్ మీ IoT హబ్‌కు కనెక్ట్ అయింది! --- **వెళ్లిచూపు**: ఈ పత్రాన్ని AI అనువాద సేవ [Co-op Translator](https://github.com/Azure/co-op-translator) ఉపయోగించి అనువదించబడింది. మేము ఖచ్చితత్వానికి ప్రయత్నిస్తూనే ఉన్నాం గానీ, ఆటోమేటిక్ అనువాదాల్లో పొరపాట్లు లేదా తప్పులున్నట్లుండవచ్చు. అసలు భాషలో ఉన్న పత్రం అధికారిక మూలంగా పరిగణించాలి. అత్యంత అవసరమైన సమాచారానికి ప్రొఫెషనల్ మానవ అనువాదం చేయించుకోవడం మేలైంది. ఈ అనువాదం వాడుక వల్ల కలిగే ఏవైనా అపార్థాలు లేదా తప్పుదారుల కోసం మేము బాధ్యత వహించము.