Share via


Cihazınızı Uzaktan İzleme çözüm hızlandırıcısına bağlama (Windows)

Bu öğreticide, Uzaktan İzleme çözüm hızlandırıcısına aşağıdaki telemetri verilerini gönderen bir Soğutucu cihazı uygulayacaksınız:

  • Sıcaklık
  • Basınç
  • Nem oranı

Kolaylık olması için kod, Soğutucu için örnek telemetri değerleri oluşturur. Cihazınıza gerçek algılayıcılar bağlayarak ve gerçek telemetri göndererek örneği genişletebilirsiniz.

Örnek cihaz ayrıca:

  • Özelliklerini açıklamak için çözüme meta veri gönderir.
  • Çözümdeki Cihazlar sayfasından tetiklenen eylemlere yanıt verir.
  • Çözümdeki Cihazlar sayfasından gelen yapılandırma değişikliklerine yanıt verir.

Bu öğreticiyi tamamlamak için etkin bir Azure hesabınızın olması gerekir. Bir hesabınız yoksa, yalnızca birkaç dakika içinde ücretsiz bir deneme hesabı oluşturabilirsiniz. Ayrıntılı bilgi için bkz. Azure Ücretsiz Deneme Sürümü.

Başlamadan önce

Cihazınız için kod yazmadan önce Uzaktan İzleme çözüm hızlandırıcınızı dağıtın ve çözüme yeni bir gerçek cihaz ekleyin.

Uzaktan İzleme çözüm hızlandırıcınızı dağıtma

Bu öğreticide oluşturduğunuz Soğutucu cihazı, uzaktan izleme çözümü hızlandırıcısının bir örneğine veri gönderir. Azure hesabınızda Uzaktan İzleme çözümü hızlandırıcısını henüz sağlamadıysanız bkz. Uzaktan İzleme çözüm hızlandırıcısını dağıtma

Uzaktan İzleme çözümünün dağıtım işlemi tamamlandığında Başlat'a tıklayarak çözüm panosunu tarayıcınızda açın.

Çözüm panosu

Cihazınızı Uzaktan İzleme çözümüne ekleme

Not

Çözümünüzde zaten bir cihaz eklediyseniz bu adımı atlayabilirsiniz. Ancak, sonraki adım cihaz bağlantı dizenizi gerektirir. Bir cihazın bağlantı dizesini Azure portal veya az iot CLI aracını kullanarak alabilirsiniz.

Bir cihazın çözüm hızlandırıcısına bağlanabilmesi için geçerli kimlik bilgilerini kullanarak kendisini IoT Hub tanımlaması gerekir. Cihazı çözüme eklerken bu kimlik bilgilerini içeren cihaz bağlantı dizesini kaydetme fırsatınız vardır. Cihaz bağlantı dizesini bu öğreticinin ilerleyen bölümlerinde istemci uygulamanıza ekleyeceksiniz.

Uzaktan İzleme çözümünüze cihaz eklemek için çözümdeki Cihaz Gezgini sayfasında aşağıdaki adımları tamamlayın:

  1. + Yeni cihaz'ı ve ardından Cihaz türü olarak Gerçek'i seçin:

    Gerçek cihaz ekleme

  2. Cihaz Kimliği olarak Fiziksel soğutucu girin. Simetrik Anahtar ve Anahtarları otomatik olarak oluştur seçeneklerini belirleyin:

    Cihaz seçeneklerini belirleme

  3. Uygula'yı seçin. Ardından Cihaz Kimliği, Birincil Anahtar ve Bağlantı dizesi birincil anahtar değerlerini not edin:

    Kimlik bilgilerini alma

Şimdi Uzaktan İzleme çözümü hızlandırıcısına gerçek bir cihaz eklediniz ve cihaz bağlantı dizesini not ettiniz. Aşağıdaki bölümlerde, çözümünüzle bağlantı kurmak için cihaz bağlantı dizesini kullanan istemci uygulamasını uygulayacaksınız.

İstemci uygulaması yerleşik Soğutucu cihaz modelini uygular. Çözüm hızlandırıcısı cihaz modeli, bir cihaz hakkında aşağıdakileri belirtir:

  • Cihazın çözüme rapor verdiği özellikler. Örneğin, bir Chiller cihazı üretici yazılımı ve konumu hakkında bilgi bildirir.
  • Cihazın çözüme gönderdiği telemetri türleri. Örneğin soğutucu cihazı sıcaklık , nem ve basınç değerlerini gönderir.
  • Cihazda çalıştırmak için çözümden zamanlayabileceğiniz yöntemler. Örneğin, bir Chiller cihazının Reboot, FirmwareUpdate, EmergencyValveRelease ve IncreasePressure yöntemlerini uygulaması gerekir.

Bu öğreticide gerçek bir cihazı Uzaktan İzleme çözümü hızlandırıcısına nasıl bağlayacağınız gösterilmektedir.

Kısıtlı cihazlarda çalışan çoğu ekli uygulamada olduğu gibi, cihaz uygulamasının istemci kodu C dilinde yazılır. Bu öğreticide, cihaz istemci uygulamasını Windows çalıştıran bir makinede oluşturacaksınız.

Bir cihazın benzetimini yapmak istiyorsanız bkz. Yeni bir simülasyon cihazı oluşturma ve test etme.

Önkoşullar

Bu nasıl yapılır kılavuzundaki adımları tamamlamak için, Gerekli geliştirme araçlarını ve kitaplıklarını Windows makinenize eklemek üzere Windows geliştirme ortamınızı ayarlama adımlarını izleyin.

Kodu görüntüleme

Bu kılavuzda kullanılan örnek kod , Azure IoT C SDK'ları GitHub deposunda kullanılabilir.

Kaynak kodu indirme ve projeyi hazırlama

Projeyi hazırlamak için GitHub'dan Azure IoT C SDK'ları deposunu kopyalayın .

Örnek samples /solutions/remote_monitoring_client klasöründe bulunur.

samples/solutions/remote_monitoring_client klasöründeki remote_monitoring.c dosyasını bir metin düzenleyicisinde açın.

Kod kılavuzu

Bu bölümde, örnek kodun bazı önemli bölümleri açıklanır ve bunların Uzaktan İzleme çözüm hızlandırıcısı ile nasıl ilişkili olduğu açıklanır.

Aşağıdaki kod parçacığı, cihazın özelliklerini açıklayan bildirilen özelliklerin nasıl tanımlandığını gösterir. Bu özellikler şunlardır:

  • Çözüm hızlandırıcısının cihazı haritaya eklemesini sağlamak için cihazın konumu.
  • Geçerli üretici yazılımı sürümü.
  • Cihazın desteklediği yöntemlerin listesi.
  • Cihaz tarafından gönderilen telemetri iletilerinin şeması.
typedef struct MESSAGESCHEMA_TAG
{
    char* name;
    char* format;
    char* fields;
} MessageSchema;

typedef struct TELEMETRYSCHEMA_TAG
{
    MessageSchema messageSchema;
} TelemetrySchema;

typedef struct TELEMETRYPROPERTIES_TAG
{
    TelemetrySchema temperatureSchema;
    TelemetrySchema humiditySchema;
    TelemetrySchema pressureSchema;
} TelemetryProperties;

typedef struct CHILLER_TAG
{
    // Reported properties
    char* protocol;
    char* supportedMethods;
    char* type;
    char* firmware;
    FIRMWARE_UPDATE_STATUS firmwareUpdateStatus;
    char* location;
    double latitude;
    double longitude;
    TelemetryProperties telemetry;

    // Manage firmware update process
    char* new_firmware_version;
    char* new_firmware_URI;
} Chiller;

Örnek, Parson kitaplığını kullanarak bu veri yapısını seri hale getiren bir serializeToJson işlevi içerir.

Örnek, istemci çözüm hızlandırıcısıyla etkileşim kurarken bilgileri konsola yazdıran birkaç geri çağırma işlevi içerir:

  • connection_status_callback
  • send_confirm_callback
  • reported_state_callback
  • device_method_callback

Aşağıdaki kod parçacığında device_method_callback işlevi gösterilmektedir. Bu işlev, çözüm hızlandırıcısından bir yöntem çağrısı alındığında gerçekleştirecek eylemi belirler. işlevi userContextCallback parametresindeki Chiller veri yapısına bir başvuru alır. userContextCallback değeri, geri çağırma işlevi ana işlevde yapılandırıldığında ayarlanır:

static int device_method_callback(const char* method_name, const unsigned char* payload, size_t size, unsigned char** response, size_t* response_size, void* userContextCallback)
{
    Chiller *chiller = (Chiller *)userContextCallback;

    int result;

    (void)printf("Direct method name:    %s\r\n", method_name);

    (void)printf("Direct method payload: %.*s\r\n", (int)size, (const char*)payload);

    if (strcmp("Reboot", method_name) == 0)
    {
        MESSAGERESPONSE(201, "{ \"Response\": \"Rebooting\" }")
    }
    else if (strcmp("EmergencyValveRelease", method_name) == 0)
    {
        MESSAGERESPONSE(201, "{ \"Response\": \"Releasing emergency valve\" }")
    }
    else if (strcmp("IncreasePressure", method_name) == 0)
    {
        MESSAGERESPONSE(201, "{ \"Response\": \"Increasing pressure\" }")
    }
    else if (strcmp("FirmwareUpdate", method_name) == 0)
    {
        if (chiller->firmwareUpdateStatus != IDLE)
        {
            (void)printf("Attempt to invoke firmware update out of order\r\n");
            MESSAGERESPONSE(400, "{ \"Response\": \"Attempting to initiate a firmware update out of order\" }")
        }
        else
        {
            getFirmwareUpdateValues(chiller, payload);

            if (chiller->new_firmware_version != NULL && chiller->new_firmware_URI != NULL)
            {
                // Create a thread for the long-running firmware update process.
                THREAD_HANDLE thread_apply;
                THREADAPI_RESULT t_result = ThreadAPI_Create(&thread_apply, do_firmware_update, chiller);
                if (t_result == THREADAPI_OK)
                {
                    (void)printf("Starting firmware update thread\r\n");
                    MESSAGERESPONSE(201, "{ \"Response\": \"Starting firmware update thread\" }")
                }
                else
                {
                    (void)printf("Failed to start firmware update thread\r\n");
                    MESSAGERESPONSE(500, "{ \"Response\": \"Failed to start firmware update thread\" }")
                }
            }
            else
            {
                (void)printf("Invalid method payload\r\n");
                MESSAGERESPONSE(400, "{ \"Response\": \"Invalid payload\" }")
            }
        }
    }
    else
    {
        // All other entries are ignored.
        (void)printf("Method not recognized\r\n");
        MESSAGERESPONSE(400, "{ \"Response\": \"Method not recognized\" }")
    }

    return result;
}

Çözüm hızlandırıcısı üretici yazılımı güncelleştirme yöntemini çağırdığında, örnek JSON yükünü seri durumdan çıkararak güncelleştirme işlemini tamamlamak için bir arka plan iş parçacığı başlatır. Aşağıdaki kod parçacığı, iş parçacığında çalışan do_firmware_update gösterir:

/*
 This is a thread allocated to process a long-running device method call.
 It uses device twin reported properties to communicate status values
 to the Remote Monitoring solution accelerator.
*/
static int do_firmware_update(void *param)
{
    Chiller *chiller = (Chiller *)param;
    printf("Running simulated firmware update: URI: %s, Version: %s\r\n", chiller->new_firmware_URI, chiller->new_firmware_version);

    printf("Simulating download phase...\r\n");
    chiller->firmwareUpdateStatus = DOWNLOADING;
    sendChillerReportedProperties(chiller);

    ThreadAPI_Sleep(5000);

    printf("Simulating apply phase...\r\n");
    chiller->firmwareUpdateStatus = APPLYING;
    sendChillerReportedProperties(chiller);

    ThreadAPI_Sleep(5000);

    printf("Simulating reboot phase...\r\n");
    chiller->firmwareUpdateStatus = REBOOTING;
    sendChillerReportedProperties(chiller);

    ThreadAPI_Sleep(5000);

    size_t size = strlen(chiller->new_firmware_version) + 1;
    (void)memcpy(chiller->firmware, chiller->new_firmware_version, size);

    chiller->firmwareUpdateStatus = IDLE;
    sendChillerReportedProperties(chiller);

    return 0;
}

Aşağıdaki kod parçacığı, istemcinin çözüm hızlandırıcısına nasıl telemetri iletisi gönderdiğini gösterir. İleti özellikleri, çözüm hızlandırıcısının panoda telemetriyi görüntülemesine yardımcı olacak ileti şemasını içerir:

static void send_message(IOTHUB_DEVICE_CLIENT_HANDLE handle, char* message, char* schema)
{
    IOTHUB_MESSAGE_HANDLE message_handle = IoTHubMessage_CreateFromString(message);
    if (message_handle != NULL)
    {
        // Set system properties
        (void)IoTHubMessage_SetMessageId(message_handle, "MSG_ID");
        (void)IoTHubMessage_SetCorrelationId(message_handle, "CORE_ID");
        (void)IoTHubMessage_SetContentTypeSystemProperty(message_handle, "application%2fjson");
        (void)IoTHubMessage_SetContentEncodingSystemProperty(message_handle, "utf-8");

        // Set application properties
        MAP_HANDLE propMap = IoTHubMessage_Properties(message_handle);
        (void)Map_AddOrUpdate(propMap, "$$MessageSchema", schema);
        (void)Map_AddOrUpdate(propMap, "$$ContentType", "JSON");

        time_t now = time(0);
        struct tm* timeinfo;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4996) /* Suppress warning about possible unsafe function in Visual Studio */
#endif
        timeinfo = gmtime(&now);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
        char timebuff[50];
        strftime(timebuff, 50, "%Y-%m-%dT%H:%M:%SZ", timeinfo);
        (void)Map_AddOrUpdate(propMap, "$$CreationTimeUtc", timebuff);

        IoTHubDeviceClient_SendEventAsync(handle, message_handle, send_confirm_callback, NULL);

        IoTHubMessage_Destroy(message_handle);
    }
}

Örnekteki ana işlev:

  • SDK alt sistemini başlatır ve kapatır.
  • Soğutucu veri yapısını başlatır.
  • Bildirilen özellikleri çözüm hızlandırıcısına gönderir.
  • Cihaz yöntemi geri çağırma işlevini yapılandırıyor.
  • Sanal telemetri değerlerini çözüm hızlandırıcısına gönderir.
int main(void)
{
    srand((unsigned int)time(NULL));
    double minTemperature = 50.0;
    double minPressure = 55.0;
    double minHumidity = 30.0;
    double temperature = 0;
    double pressure = 0;
    double humidity = 0;

    (void)printf("This sample simulates a Chiller device connected to the Remote Monitoring solution accelerator\r\n\r\n");

    // Used to initialize sdk subsystem
    (void)IoTHub_Init();

    (void)printf("Creating IoTHub handle\r\n");
    // Create the iothub handle here
    device_handle = IoTHubDeviceClient_CreateFromConnectionString(connectionString, MQTT_Protocol);
    if (device_handle == NULL)
    {
        (void)printf("Failure creating IotHub device. Hint: Check your connection string.\r\n");
    }
    else
    {
        // Setting connection status callback to get indication of connection to iothub
        (void)IoTHubDeviceClient_SetConnectionStatusCallback(device_handle, connection_status_callback, NULL);

        Chiller chiller;
        memset(&chiller, 0, sizeof(Chiller));
        chiller.protocol = "MQTT";
        chiller.supportedMethods = "Reboot,FirmwareUpdate,EmergencyValveRelease,IncreasePressure";
        chiller.type = "Chiller";
        size_t size = strlen(initialFirmwareVersion) + 1;
        chiller.firmware = malloc(size);
        if (chiller.firmware == NULL)
        {
            (void)printf("Chiller Firmware failed to allocate memory.\r\n");
        }
        else
        {
            memcpy(chiller.firmware, initialFirmwareVersion, size);
            chiller.firmwareUpdateStatus = IDLE;
            chiller.location = "Building 44";
            chiller.latitude = 47.638928;
            chiller.longitude = -122.13476;
            chiller.telemetry.temperatureSchema.messageSchema.name = "chiller-temperature;v1";
            chiller.telemetry.temperatureSchema.messageSchema.format = "JSON";
            chiller.telemetry.temperatureSchema.messageSchema.fields = "{\"temperature\":\"Double\",\"temperature_unit\":\"Text\"}";
            chiller.telemetry.humiditySchema.messageSchema.name = "chiller-humidity;v1";
            chiller.telemetry.humiditySchema.messageSchema.format = "JSON";
            chiller.telemetry.humiditySchema.messageSchema.fields = "{\"humidity\":\"Double\",\"humidity_unit\":\"Text\"}";
            chiller.telemetry.pressureSchema.messageSchema.name = "chiller-pressure;v1";
            chiller.telemetry.pressureSchema.messageSchema.format = "JSON";
            chiller.telemetry.pressureSchema.messageSchema.fields = "{\"pressure\":\"Double\",\"pressure_unit\":\"Text\"}";

            sendChillerReportedProperties(&chiller);

            (void)IoTHubDeviceClient_SetDeviceMethodCallback(device_handle, device_method_callback, &chiller);

            while (1)
            {
                temperature = minTemperature + ((double)(rand() % 10) + 5);
                pressure = minPressure + ((double)(rand() % 10) + 5);
                humidity = minHumidity + ((double)(rand() % 20) + 5);

                if (chiller.firmwareUpdateStatus == IDLE)
                {
                    (void)printf("Sending sensor value Temperature = %f %s,\r\n", temperature, "F");
                    (void)sprintf_s(msgText, sizeof(msgText), "{\"temperature\":%.2f,\"temperature_unit\":\"F\"}", temperature);
                    send_message(device_handle, msgText, chiller.telemetry.temperatureSchema.messageSchema.name);


                    (void)printf("Sending sensor value Pressure = %f %s,\r\n", pressure, "psig");
                    (void)sprintf_s(msgText, sizeof(msgText), "{\"pressure\":%.2f,\"pressure_unit\":\"psig\"}", pressure);
                    send_message(device_handle, msgText, chiller.telemetry.pressureSchema.messageSchema.name);


                    (void)printf("Sending sensor value Humidity = %f %s,\r\n", humidity, "%");
                    (void)sprintf_s(msgText, sizeof(msgText), "{\"humidity\":%.2f,\"humidity_unit\":\"%%\"}", humidity);
                    send_message(device_handle, msgText, chiller.telemetry.humiditySchema.messageSchema.name);
                }

                ThreadAPI_Sleep(5000);
            }

            (void)printf("\r\nShutting down\r\n");

            // Clean up the iothub sdk handle and free resources
            IoTHubDeviceClient_Destroy(device_handle);
            free(chiller.firmware);
            free(chiller.new_firmware_URI);
            free(chiller.new_firmware_version);
        }
    }
    // Shutdown the sdk subsystem
    IoTHub_Deinit();

    return 0;
}

Örneği derleme ve çalıştırma

  1. remote_monitoring.c dosyasını, çözüm hızlandırıcısına bir cihaz eklerken bu nasıl yapılır kılavuzunun başında not ettiğiniz cihaz bağlantı dizesiyle değiştirecek <connectionstring> şekilde düzenleyin.

  2. SDK'yı ve uzaktan izleme istemci uygulamasını derlemek için Windows'ta C SDK'sını derleme makalesindeki adımları izleyin.

  3. Çözümü derlemek için kullandığınız komut isteminde şunu çalıştırın:

    samples\solutions\remote_monitoring_client\Release\remote_monitoring_client.exe
    

    Konsol iletileri şu şekilde görüntüler:

    • Uygulama, çözüm hızlandırıcısına örnek telemetri gönderir.
    • Çözüm panosundan çağrılan yöntemlere yanıt verir.

Cihaz telemetrisini görüntüleme

Cihazınızdan gönderilen telemetriyi çözümdeki Cihaz Gezgini sayfasında görüntüleyebilirsiniz.

  1. Cihaz Gezgini sayfasındaki cihaz listesinde sağladığınız cihazı seçin. Panelde, cihaz telemetrisinin çizimi de dahil olmak üzere cihazınızla ilgili bilgiler görüntülenir:

    Cihaz ayrıntılarına bakın

  2. Telemetri ekranını değiştirmek için Basınç'ı seçin:

    Basınç telemetri verilerini görüntüleme

  3. Cihazınızla ilgili tanılama bilgilerini görüntülemek için ekranı aşağı kaydırarak Tanılama'ya gidin:

    Cihaz tanılamalarını görüntüleme

Cihazınızda işlem yapma

Cihazlarınızda yöntemleri çağırmak için Uzaktan İzleme çözümündeki Cihaz Gezgini sayfasını kullanın. Örneğin Uzaktan İzleme çözümü soğutucu cihazları bir Yeniden başlatma yöntemi uygular.

  1. ÇözümdekiCihaz Gezgini sayfasına gitmek için Cihazlar'ı seçin.

  2. Cihaz Gezgini sayfasındaki cihaz listesinde sağladığınız cihazı seçin:

    Gerçek cihazınızı seçin

  3. Cihazınızda çağırabileceğiniz yöntemlerin listesini görüntülemek için İşler'i ve ardından Yöntemler'i seçin. Bir işi birden çok cihazda çalışacak şekilde zamanlamak için listeden birden çok cihaz seçebilirsiniz. İşler panelinde seçtiğiniz tüm cihazlarda ortak olan yöntem türleri gösterilir.

  4. Yeniden Başlat'ı seçin, iş adını RebootPhysicalChiller olarak ayarlayın ve uygula'yı seçin:

    Üretici yazılımı güncelleştirmesini zamanlama

  5. Simülasyon cihazı yöntemi işlerken cihaz kodunuzu çalıştıran konsolda bir ileti dizisi görüntülenir.

Not

Çözümdeki işin durumunu izlemek için İş Durumunu Görüntüle'yi seçin.

Sonraki adımlar

Uzaktan İzleme çözüm hızlandırıcısını özelleştirme makalesinde, çözüm hızlandırıcısını özelleştirmenin bazı yolları açıklanmaktadır.