Exemple #1
0
        public async Task OnDesiredPropertyUpdate(TwinCollection desiredProperties, object userContext)
        {
            await SetReportedPropertyAsync(LastDesiredPropertyChangePropertyName, desiredProperties.ToJson());

            Logger.LogInfo($"{DeviceID} received desired property update: {desiredProperties.ToJson()}");

            foreach (var pair in desiredProperties.AsEnumerableFlatten())
            {
                Func <object, Task> handler;
                if (_desiredPropertyUpdateHandlers.TryGetValue(pair.Key, out handler))
                {
                    try
                    {
                        await handler(pair.Value.Value.Value);

                        Logger.LogInfo($"Successfully called desired property update handler {handler.Method.Name} on {DeviceID}");
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError($"Exception raised while processing desired property {pair.Key} change on device {DeviceID}: {ex.Message}");
                    }
                }
                else
                {
                    Logger.LogWarning($"Cannot find desired property update handler for {pair.Key} on {DeviceID}");
                }
            }
        }
Exemple #2
0
        private async Task desiredPropertyUpdateCallbackMethod(TwinCollection desiredProperties, object userContext)
        {
            var desiredPropertiesJson = desiredProperties.ToJson();

            showConsoleLog($"Received desired properties update - '{desiredPropertiesJson}'");


            await UpdateConfig(desiredProperties.ToJson());
        }
        public async Task UpdateReportedPropertiesTest()
        {
            string id = "d1";

            var reported1 = new TwinCollection
            {
                ["p1"] = "vp1",
                ["p3"] = "v3"
            };

            TwinCollection receivedTwinPatch = null;
            var            twinStore         = new Mock <ITwinStore>(MockBehavior.Strict);

            twinStore.Setup(c => c.UpdateReportedProperties(id, It.IsAny <TwinCollection>()))
            .Callback <string, TwinCollection>((s, t) => receivedTwinPatch = t)
            .Returns(Task.CompletedTask);

            TwinCollection receivedTwinPatch2      = null;
            var            reportedPropertiesStore = new Mock <IReportedPropertiesStore>(MockBehavior.Strict);

            reportedPropertiesStore.Setup(r => r.InitSyncToCloud(id));
            reportedPropertiesStore.Setup(r => r.Update(id, It.IsAny <TwinCollection>()))
            .Callback <string, TwinCollection>((s, t) => receivedTwinPatch2 = t)
            .Returns(Task.CompletedTask);

            var cloudSync                   = Mock.Of <ICloudSync>();
            var twinMessageConverter        = new TwinMessageConverter();
            var connectionManager           = Mock.Of <IConnectionManager>();
            var twinCollectionConverter     = new TwinCollectionMessageConverter();
            var reportedPropertiesValidator = Mock.Of <IValidator <TwinCollection> >();
            var deviceConnectivityManager   = Mock.Of <IDeviceConnectivityManager>();

            var twinManager = new StoringTwinManager(
                connectionManager,
                twinCollectionConverter,
                twinMessageConverter,
                reportedPropertiesValidator,
                twinStore.Object,
                reportedPropertiesStore.Object,
                cloudSync,
                deviceConnectivityManager,
                TimeSpan.FromMinutes(10));

            IMessage reportedPropertiesMessage = twinCollectionConverter.ToMessage(reported1);

            // Act
            await twinManager.UpdateReportedPropertiesAsync(id, reportedPropertiesMessage);

            // Assert
            twinStore.VerifyAll();
            reportedPropertiesStore.VerifyAll();

            Assert.NotNull(receivedTwinPatch);
            Assert.NotNull(receivedTwinPatch2);
            Assert.Equal(reported1.ToJson(), receivedTwinPatch.ToJson());
            Assert.Equal(reported1.ToJson(), receivedTwinPatch2.ToJson());
        }
        private Task DesiredPropertyUpdate(TwinCollection desiredProperties, object userContext)
        {
            int size = Encoding.UTF8.GetBytes(desiredProperties.ToJson()).Length;

            return(new Task(() =>
            {
                Debug.WriteLine("Received Desired Property - size=" + size);
                Debug.WriteLine(desiredProperties.ToJson());
                if (DesiredPropertiesUpdate != null)
                {
                    DesiredPropertiesUpdate(this, desiredProperties);
                }
            }));
        }
        public async Task ClearAllReportedPropertiesAsync()
        {
            if (_deviceClient == null)
            {
                throw new Exception("Should be Initial first");
            }

            Twin twin = await GetTwinAsync();

            TwinCollection oldTC = twin.Properties.Reported;
            JObject        oldReportedProperties = JObject.Parse(oldTC.ToJson());

            TwinCollection tc = new TwinCollection();

            foreach (JProperty jp in oldReportedProperties.Properties())
            {
                if (String.Equals(jp.Name.Substring(0, 1), "$"))
                {
                    Logger.showDebug(TAG, jp.Name + " - " + jp.Value + "(internal used)");
                }
                else
                {
                    Logger.showDebug(TAG, jp.Name + " - " + jp.Value);
                    tc[jp.Name] = null;
                }
            }

            await _deviceClient.UpdateReportedPropertiesAsync(tc);
        }
Exemple #6
0
            public void CreateRootPropertyEmbeddedValuePatch()
            {
                // Format:
                //  {
                //      "samplePropertyName": {
                //          "value": 20,
                //          "ac": 200,
                //          "av": 5,
                //          "ad": "The update was successful."
                //      }
                //  }

                const string propertyName  = "someName";
                const int    propertyValue = 10;
                const int    ackCode       = 200;
                const long   ackVersion    = 2;

                TwinCollection patch = PnpConvention.CreateWritablePropertyResponse(propertyName, propertyValue, ackCode, ackVersion);

                var jObject = JObject.Parse(patch.ToJson());
                EmbeddedPropertyPatch actualPatch = jObject.ToObject <EmbeddedPropertyPatch>();

                // The property patch object should have "value", "ac" and "av" properties set. Since we did not supply an "ackDescription", "ad" should be null.
                actualPatch.Value.SerializedValue.Should().Be(JsonConvert.SerializeObject(propertyValue));
                actualPatch.Value.AckCode.Should().Be(ackCode);
                actualPatch.Value.AckVersion.Should().Be(ackVersion);
                actualPatch.Value.AckDescription.Should().BeNull();
            }
Exemple #7
0
        public Task OnDesiredPropertyUpdate(TwinCollection desiredProperties, object userContext)
        {
            Console.WriteLine("Desired property:");
            Console.WriteLine(desiredProperties.ToJson());

            return(null);
        }
        private async Task HandleTwinUpdateNotificationsAsync(TwinCollection twinUpdateRequest, object userContext)
        {
            CancellationToken cancellationToken = (CancellationToken)userContext;

            if (!cancellationToken.IsCancellationRequested)
            {
                var reportedProperties = new TwinCollection();

                _logger.LogInformation($"Twin property update requested: \n{twinUpdateRequest.ToJson()}");

                // For the purpose of this sample, we'll blindly accept all twin property write requests.
                foreach (KeyValuePair <string, object> desiredProperty in twinUpdateRequest)
                {
                    _logger.LogInformation($"Setting property {desiredProperty.Key} to {desiredProperty.Value}.");
                    reportedProperties[desiredProperty.Key] = desiredProperty.Value;
                }

                // For the purpose of this sample, we'll blindly accept all twin property write requests.
                await RetryOperationHelper.RetryTransientExceptionsAsync(
                    operationName : "UpdateReportedProperties",
                    asyncOperation : async() => await s_deviceClient.UpdateReportedPropertiesAsync(reportedProperties, cancellationToken),
                    shouldExecuteOperation : () => IsDeviceConnected,
                    logger : _logger,
                    exceptionsToBeIgnored : _exceptionsToBeIgnored,
                    cancellationToken : cancellationToken);
            }
        }
Exemple #9
0
        private static async Task OnDesiredChange(TwinCollection desiredProperties, object userContext)
        {
            DeviceProperties newProps;

            try
            {
                newProps = JsonConvert.DeserializeObject <DeviceProperties>(desiredProperties.ToJson());
            } catch (JsonException ex)
            {
                Console.WriteLine("Invalid properties!");
                return;
            }

            if (newProps.SoftwareInfo != null)
            {
                if (newProps.SoftwareInfo.Name != null)
                {
                    deviceProps.SoftwareInfo.Name = newProps.SoftwareInfo.Name;
                }
                if (newProps.SoftwareInfo.Version != null)
                {
                    deviceProps.SoftwareInfo.Version = newProps.SoftwareInfo.Version;
                }
            }
            if (newProps.Errors != null)
            {
                deviceProps.Errors = newProps.Errors;
            }

            var newReported = new TwinCollection(JsonConvert.SerializeObject(deviceProps));
            await deviceClient.UpdateReportedPropertiesAsync(newReported);
        }
Exemple #10
0
 private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext)
 {
     await Task.Run(() => {
         Console.WriteLine("New desired properties received:");
         Console.WriteLine(desiredProperties.ToJson());
     });
 }
        // UNCOMMENT OnDesiredPropertyChanged method below here
        private static async Task OnDesiredPropertyChanged(
            TwinCollection desiredProperties,
            object userContext)
        {
            try
            {
                // Update the Cheese Cave Simulator properties
                cheeseCave.DesiredHumidity    = desiredProperties["humidity"];
                cheeseCave.DesiredTemperature = desiredProperties["temperature"];
                ConsoleHelper.WriteGreenMessage("Setting desired humidity to " + desiredProperties["humidity"]);
                ConsoleHelper.WriteGreenMessage("Setting desired temperature to " + desiredProperties["temperature"]);

                // Report the properties back to the IoT Hub.
                var reportedProperties = new TwinCollection();
                reportedProperties["fanstate"]    = cheeseCave.FanState.ToString();
                reportedProperties["humidity"]    = cheeseCave.DesiredHumidity;
                reportedProperties["temperature"] = cheeseCave.DesiredTemperature;
                await deviceClient.UpdateReportedPropertiesAsync(reportedProperties);

                ConsoleHelper.WriteGreenMessage("\nTwin state reported: " + reportedProperties.ToJson());
            }
            catch
            {
                ConsoleHelper.WriteRedMessage("Failed to update device twin");
            }
        }
Exemple #12
0
        //  Desired Property Handler
        private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext)
        {
            Logger.Info($"\tDesired property changed:{desiredProperties.ToJson()}");
            Device device = userContext as Device;

            Logger.Info("\tSending current time as reported property");
            TwinCollection reportedProperties = new TwinCollection();

            reportedProperties["status_updated_time"] = DateTime.Now;
            reportedProperties["status_updated"]      = true;

            if (new Random().Next(1, 100) >= 80)
            {
                reportedProperties["status"] = "ok";
            }
            else
            {
                reportedProperties["status"] = "failed";
            }

            DeviceClient client = CreateDeviceClient(_appSettings.IoTHubUrl, device.Id, device.Authentication.SymmetricKey.SecondaryKey);

            //  Update Reported Properties
            await client.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false);
        }
        // INSERT OnDesiredPropertyChanged method below here
        private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext)
        {
            Console.WriteLine("Desired Twin Property Changed:");
            Console.WriteLine($"{desiredProperties.ToJson()}");

            // Read the desired Twin Properties
            if (desiredProperties.Contains("telemetryDelay"))
            {
                string desiredTelemetryDelay = desiredProperties["telemetryDelay"];
                if (desiredTelemetryDelay != null)
                {
                    telemetryDelay = int.Parse(desiredTelemetryDelay);
                }
                // if desired telemetryDelay is null or unspecified, don't change it
            }


            // Report Twin Properties
            var reportedProperties = new TwinCollection();

            reportedProperties["telemetryDelay"] = telemetryDelay.ToString();
            await deviceClient.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false);

            Console.WriteLine("Reported Twin Properties:");
            Console.WriteLine($"{reportedProperties.ToJson()}");
        }
        public async Task SendPropertyAsync(MessageData message, CancellationToken ct)
        {
            TwinCollection reportedPropertiesEdge = new TwinCollection();

            if (message.EventMessageData != null && message.EventMessageData.EventValues.Count > 0)
            {
                foreach (var eventValue in message.EventMessageData.EventValues)
                {
                    reportedPropertiesEdge[eventValue.Name] = eventValue.Value;
                }
            }
            else
            {
                reportedPropertiesEdge[message.DataChangeMessageData.Key] = message.DataChangeMessageData.Value;
            }

            var eventMessage = new Message(Encoding.UTF8.GetBytes(reportedPropertiesEdge.ToJson()));

            eventMessage.Properties["x-reported-properties"] = "true";
            eventMessage.Properties["endpointId"]            = message?.DataChangeMessageData?.EndpointId ?? message?.EventMessageData?.EndpointId;

            if (_iotHubClient == null)
            {
                await _edgeHubClient.UpdateReportedPropertiesAsync(reportedPropertiesEdge, ct).ConfigureAwait(false);

                await _edgeHubClient.SendEventAsync(eventMessage).ConfigureAwait(false);
            }
            else
            {
                await _iotHubClient.UpdateReportedPropertiesAsync(reportedPropertiesEdge, ct).ConfigureAwait(false);

                await _iotHubClient.SendEventAsync(eventMessage).ConfigureAwait(false);
            }
        }
Exemple #15
0
        public async Task CanListenForDesiredPropertyUpdates()
        {
            var    update                    = new TaskCompletionSource <IMessage>();
            var    cloudListener             = new Mock <ICloudListener>();
            string deviceConnectionStringKey = "device2ConnStrKey";

            cloudListener.Setup(x => x.OnDesiredPropertyUpdates(It.IsAny <IMessage>()))
            .Callback((IMessage m) => update.TrySetResult(m))
            .Returns(TaskEx.Done);

            ICloudProxy cloudProxy = await this.GetCloudProxyWithConnectionStringKey(deviceConnectionStringKey);

            cloudProxy.BindCloudListener(cloudListener.Object);
            await cloudProxy.SetupDesiredPropertyUpdatesAsync();

            var desired = new TwinCollection()
            {
                ["desiredPropertyTest"] = Guid.NewGuid().ToString()
            };

            await UpdateDesiredProperty(ConnectionStringHelper.GetDeviceId(await SecretsHelper.GetSecretFromConfigKey(deviceConnectionStringKey)), desired);

            await update.Task;
            await cloudProxy.RemoveDesiredPropertyUpdatesAsync();

            IMessage expected = new EdgeMessage.Builder(Encoding.UTF8.GetBytes(desired.ToJson())).Build();

            expected.SystemProperties[SystemProperties.EnqueuedTime] = "";
            expected.SystemProperties[SystemProperties.Version]      = desired.Version.ToString();
            IMessage actual = update.Task.Result;

            Assert.Equal(expected.Body, actual.Body);
            Assert.Equal(expected.Properties, actual.Properties);
            Assert.Equal(expected.SystemProperties.Keys, actual.SystemProperties.Keys);
        }
        public async Task UpdateReportedPropertiesAsync(TwinCollection reportedProperties)
        {
            _logger.LogInfo("UpdateReportedPropertiesAsync called");
            _logger.LogInfo($"UpdateReportedPropertiesAsync: reportedProperties: {reportedProperties.ToJson(Formatting.Indented)}");

            await Task.FromResult(0);
        }
Exemple #17
0
        public DesiredPropertiesData(TwinCollection twinCollection)
        {
            Console.WriteLine($"Updating desired properties {twinCollection.ToJson(Formatting.Indented)}");
            try
            {
                if (twinCollection.Contains("SendData") && twinCollection["SendData"] != null)
                {
                    _sendData = twinCollection["SendData"];
                }

                if (twinCollection.Contains("SendInterval") && twinCollection["SendInterval"] != null)
                {
                    _sendInterval = twinCollection["SendInterval"];
                }
            }
            catch (AggregateException aexc)
            {
                foreach (var exception in aexc.InnerExceptions)
                {
                    Console.WriteLine($"[ERROR] Could not retrieve desired properties {aexc.Message}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[ERROR] Reading desired properties failed with {ex.Message}");
            }
            finally
            {
                Console.WriteLine($"Value for SendData = {_sendData}");
                Console.WriteLine($"Value for SendInterval = {_sendInterval}");
            }
        }
        private static async Task DesiredPropertyUpdateHandler(TwinCollection desiredProperties, object userContext)
        {
            var deviceClient = (DeviceClient)userContext;
            var dpJson       = desiredProperties.ToJson();

            AppStreamWriter.WriteLine($"Updated:{dpJson}");
        }
        public void FromMessageTest()
        {
            // Arrange
            var collection = new TwinCollection()
            {
                ["prop"]     = "value",
                ["$version"] = 1
            };
            string correlationId = Guid.NewGuid().ToString();

            byte[]   data    = Encoding.UTF8.GetBytes(collection.ToJson());
            IMessage message = new EdgeMessage.Builder(data)
                               .SetSystemProperties(
                new Dictionary <string, string>
            {
                [SystemProperties.CorrelationId] = correlationId
            })
                               .Build();
            IMessageConverter <AmqpMessage> messageConverter = new AmqpTwinMessageConverter();

            // Act
            AmqpMessage amqpMessage = messageConverter.FromMessage(message);

            // Assert
            Assert.NotNull(amqpMessage);
            Assert.Equal(data, amqpMessage.GetPayloadBytes());
            Assert.Equal(correlationId, amqpMessage.Properties.CorrelationId.ToString());
        }
        private async Task DesiredPropertyUpdateCallback(TwinCollection desiredProperties, object userContext)
        {
            this.logger.LogTrace($"Received desired updates [{desiredProperties.ToJson()}]");
            var aDate = GetPropertyValue <DateTime>(desiredProperties, "aDate");

            if (aDate != null)
            {
                await AckDesiredPropertyReadAsync("aDate", aDate, 200, "property synced", desiredProperties.Version);
            }
            else
            {
                logger.LogError("Cant parse desired props");
            }

            var aDateTime = GetPropertyValue <DateTime>(desiredProperties, "aDateTime");

            if (aDateTime != null)
            {
                await AckDesiredPropertyReadAsync("aDateTime", aDateTime, 200, "property synced", desiredProperties.Version);
            }
            else
            {
                logger.LogError("Cant parse desired props");
            }
        }
        public async Task <bool> UpdateReportedPropertiesAsync(TwinCollection reportedProperties)
        {
            try
            {
                this.deviceClient.OperationTimeoutInMilliseconds = 120000;

                this.SetRetry(true);

                string reportedPropertiesJson = string.Empty;
                if (Logger.LoggerLevel == LogLevel.Debug)
                {
                    reportedPropertiesJson = reportedProperties.ToJson(Newtonsoft.Json.Formatting.None);
                    Logger.Log(this.devEUI, $"updating twins {reportedPropertiesJson}", LogLevel.Debug);
                }

                await this.deviceClient.UpdateReportedPropertiesAsync(reportedProperties);

                if (Logger.LoggerLevel == LogLevel.Debug)
                {
                    Logger.Log(this.devEUI, $"twins updated {reportedPropertiesJson}", LogLevel.Debug);
                }

                return(true);
            }
            catch (Exception ex)
            {
                Logger.Log(this.devEUI, $"could not update twins with error: {ex.Message}", LogLevel.Error);
                return(false);
            }
            finally
            {
                this.SetRetry(false);
            }
        }
        public async Task UpdateTest()
        {
            // Arrange
            string id = "d1";
            IEntityStore <string, TwinStoreEntity> rpEntityStore = GetReportedPropertiesEntityStore();

            TwinCollection receivedReportedProperties = null;
            var            cloudSync = new Mock <ICloudSync>();

            cloudSync.Setup(c => c.UpdateReportedProperties(id, It.IsAny <TwinCollection>()))
            .Callback <string, TwinCollection>((s, collection) => receivedReportedProperties = collection)
            .ReturnsAsync(true);

            var reportedPropertiesStore = new ReportedPropertiesStore(rpEntityStore, cloudSync.Object, Option.None <TimeSpan>());

            var rbase = new TwinCollection
            {
                ["p1"] = "v1",
                ["p2"] = "v2"
            };

            // Act
            await reportedPropertiesStore.Update(id, rbase);

            await reportedPropertiesStore.SyncToCloud(id);

            // Assert
            Assert.NotNull(receivedReportedProperties);
            Assert.Equal(receivedReportedProperties.ToJson(), rbase.ToJson());
        }
Exemple #23
0
        private async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext)
        {
            whiteMessage("Desired Twin Property Changed:");
            whiteMessage($"{desiredProperties.ToJson()}");

            // Read the desired Twin Properties.
            if (desiredProperties.Contains("fanstate") & fanState != stateEnum.failed)
            {
                string desiredFanState = desiredProperties["fanstate"];
                desiredFanState = desiredFanState.ToLower();
                if (desiredFanState == "on" || desiredFanState == "off")
                {
                    fanState = (stateEnum)Enum.Parse(typeof(stateEnum), desiredFanState);
                    greenMessage($"Set the fan to: {desiredFanState}");
                }
                else
                {
                    redMessage($"Illegal fan state received: {desiredFanState}");
                }
            }

            if (desiredProperties.Contains("temperature"))
            {
                string desiredTemperatureString = desiredProperties["temperature"];
                try
                {
                    desiredTemperature = double.Parse(desiredTemperatureString);
                    greenMessage($"Setting the desired temperature to: {desiredTemperatureString}");
                }
                catch
                {
                    redMessage($"Illegal temperature received: {desiredTemperatureString}");
                }
            }

            if (desiredProperties.Contains("humidity"))
            {
                string desiredHumidityString = desiredProperties["humidity"];
                try
                {
                    desiredHumidity = double.Parse(desiredHumidityString);
                    greenMessage($"Setting the desired humidity to: {desiredHumidityString}");
                }
                catch
                {
                    redMessage($"Illegal humidity received: {desiredHumidityString}");
                }
            }

            // Report Twin properties.
            var reportedProperties = new TwinCollection();

            reportedProperties["fanstate"]    = fanState.ToString();
            reportedProperties["humidity"]    = desiredHumidity;
            reportedProperties["temperature"] = desiredTemperature;
            await s_deviceClient.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false);

            greenMessage($"Reported Twin Properties: {reportedProperties.ToJson()}");
        }
Exemple #24
0
        static async Task RetreiveListOfSupportedMethods(string deviceId)
        {
            Twin twin = await registryManager.GetTwinAsync(deviceId);

            TwinCollection x = twin.Properties.Reported["SupportedMethods"];

            Console.WriteLine(x.ToJson());
        }
        private Task TwinResponse(TwinCollection desiredProperties, object userContext)
        {
            string result = "{\"result\":\"Executed twin update\"}";

            txtStatus.Invoke((MethodInvoker) delegate {
                txtDesired.AppendText("Twin updaded: " + desiredProperties.ToJson() + Environment.NewLine);
            });
            return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200)));
        }
Exemple #26
0
        Task OnDesiredPropertiesChangeAsync(TwinCollection desiredProperties, object userContext)
        {
            Console.WriteLine("\tDesired property changed:");
            Console.WriteLine($"\t{desiredProperties.ToJson()}");

            PopulateDesiredFirmwareFromDesiredProperties(desiredProperties, false);

            return(Task.CompletedTask);
        }
        private async Task DesiredPropertyUpdateCallback(TwinCollection desiredProperties, object userContext)
        {
            this.logger.LogWarning($"Received desired updates [{desiredProperties.ToJson()}]");
            var orchProp = GetPropertyValue <Orchestrator>(desiredProperties, "Orchestrator");

            await AckDesiredPropertyReadAsync("Orchestrator", orchProp, 200, "property synced", desiredProperties.Version);

            this.logger.LogWarning("Prop synced");
        }
Exemple #28
0
        static void ValidateTwinCollectionSize(TwinCollection collection)
        {
            long size = Encoding.UTF8.GetByteCount(collection.ToJson());

            if (size > TwinPropertyDocMaxLength)
            {
                throw new InvalidOperationException($"Twin properties size {size} exceeds maximum {TwinPropertyDocMaxLength}");
            }
        }
        static Task OnDesiredPropertiesUpdate(TwinCollection desiredPropertiesPatch, object userContext)
        {
            try
            {
                // At this point just update the configure configuration.
                if (desiredPropertiesPatch.Contains("MessageInterval"))
                {
                    m_MessageInterval = (int)desiredPropertiesPatch["MessageInterval"];
                }
                if (desiredPropertiesPatch.Contains("SensorLocation"))
                {
                    m_SensorLocation = (string)desiredPropertiesPatch["SensorLocation"];
                    Console.WriteLine("Loading Desired SensorLocation: {0}", m_SensorLocation);
                }
                if (desiredPropertiesPatch.Contains("ActivateCam"))
                {
                    bool desiredSendDataValue = (bool)desiredPropertiesPatch["ActivateCam"];
                    if (desiredSendDataValue != m_ActivateCam && !desiredSendDataValue)
                    {
                        Console.WriteLine("Sending data disabled. Change twin configuration to start sending again.");
                    }

                    m_ActivateCam = desiredSendDataValue;
                }
                if (desiredPropertiesPatch.Contains("Sensor_Temperature_Min"))
                {
                    m_Sensor_Temperature_Min = (int)desiredPropertiesPatch["Sensor_Temperature_Min"];
                }
                if (desiredPropertiesPatch.Contains("Sensor_Temperature_Max"))
                {
                    m_Sensor_Temperature_Max = (int)desiredPropertiesPatch["Sensor_Temperature_Max"];
                }
                var moduleClient = (ModuleClient)userContext;
                var patch        = new TwinCollection(
                    $"{{ \"ActivateCam\":{m_ActivateCam.ToString().ToLower()}, \"MessageInterval\": {m_MessageInterval}, \"Sensor_Temperature_Min\": {m_Sensor_Temperature_Min}, \"Sensor_Temperature_Max\": {m_Sensor_Temperature_Max}, \"SensorLocation\": \"{m_SensorLocation}\"}}"
                    );

                //patch["SensorLocation"] = m_SensorLocation;
                Console.WriteLine("Updating Desired Twin Properties: {0}", patch.ToJson());
                moduleClient.UpdateReportedPropertiesAsync(patch); // Just report back last desired property.
            }
            catch (AggregateException ex)
            {
                foreach (Exception exception in ex.InnerExceptions)
                {
                    Console.WriteLine();
                    Console.WriteLine("Error when receiving desired property: {0}", exception);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine();
                Console.WriteLine("Error when receiving desired property: {0}", ex.Message);
            }

            return(Task.CompletedTask);
        }
 public DesiredPropertiesData(TwinCollection twinCollection)
 {
     Console.WriteLine($"Updating desired properties {twinCollection.ToJson(Formatting.Indented)}");
     try
     {
         if (twinCollection.Contains("SendData") && twinCollection["SendData"] != null)
         {
             _sendData = twinCollection["SendData"];
         }
         if (twinCollection.Contains("DeviceLongitude") && twinCollection["DeviceLongitude"] != null)
         {
             _deviceLongitude = twinCollection["DeviceLongitude"];
         }
         if (twinCollection.Contains("DeviceLatitude") && twinCollection["DeviceLatitude"] != null)
         {
             _deviceLatitude = twinCollection["DeviceLatitude"];
         }
         if (twinCollection.Contains("ServerHostName") && twinCollection["ServerHostName"] != null)
         {
             _serverHostname = twinCollection["ServerHostName"];
         }
         if (twinCollection.Contains("ServerBasePort") && twinCollection["ServerBasePort"] != null)
         {
             _serverBasePort = twinCollection["ServerBasePort"];
         }
         if (twinCollection.Contains("CarDetectionServerHostname") && twinCollection["CarDetectionServerHostname"] != null)
         {
             _carDetectionServerHostname = twinCollection["CarDetectionServerHostname"];
         }
         if (twinCollection.Contains("CarDetectionServerBasePort") && twinCollection["CarDetectionServerBasePort"] != null)
         {
             _carDetectionServerBasePort = twinCollection["CarDetectionServerBasePort"];
         }
     }
     catch (AggregateException aexc)
     {
         foreach (var exception in aexc.InnerExceptions)
         {
             Console.WriteLine($"[ERROR] Could not retrieve desired properties {aexc.Message}");
         }
     }
     catch (Exception ex)
     {
         Console.WriteLine($"[ERROR] Reading desired properties failed with {ex.Message}");
     }
     finally
     {
         Console.WriteLine($"Value for SendData = {_sendData}");
         Console.WriteLine($"Value for DeviceLatitude = {_deviceLatitude}");
         Console.WriteLine($"Value for DeviceLongitude = {_deviceLongitude}");
         Console.WriteLine($"Value for ServerHostname = {_serverHostname}");
         Console.WriteLine($"Value for ServerBasePort = {_serverBasePort}");
         Console.WriteLine($"Value for CarDetectionServerHostname = {_carDetectionServerHostname}");
         Console.WriteLine($"Value for CarDetectionServerHostname = {_carDetectionServerBasePort}");
     }
 }