Ejemplo n.º 1
0
        public void UpdateUtilityAppendMultipleOperations()
        {
            var    op           = new UpdateOperationsUtility();
            string addPath      = "testPath1";
            int    addValue     = 10;
            string replacePath  = "testpath2";
            int    replaceValue = 20;

            op.AppendAddPropertyOp(addPath, addValue);
            op.AppendReplacePropertyOp(replacePath, replaceValue);
            string operations = op.Serialize();

            // There should be two operations added.
            var jArray = JArray.Parse(operations);

            jArray.Count.Should().Be(2);

            // The patch operation added should have an "add" and a "replace" operation.
            var expectedOperations = new List <string> {
                Add, Replace
            };
            var actualOperations = new List <string>();

            foreach (JObject item in jArray)
            {
                actualOperations.Add(item.Value <string>(Op));
            }
            actualOperations.Should().OnlyContain(item => expectedOperations.Contains(item));
        }
        public static string GetRelationshipUpdatePayload(string propertyName, bool propertyValue)
        {
            var uou = new UpdateOperationsUtility();

            uou.AppendReplaceOp(propertyName, propertyValue);
            return(RemoveNewLines(uou.Serialize()));
        }
Ejemplo n.º 3
0
        public void UpdateUtilityAppendsReplaceComponentOp()
        {
            var    op       = new UpdateOperationsUtility();
            string path     = "testPath";
            string property = "someProperty";
            int    value    = 10;

            op.AppendReplaceComponentOp(path, new Dictionary <string, object> {
                { property, value }
            });
            string operations = op.Serialize();

            // There should be a single operation added.
            var jArray = JArray.Parse(operations);

            jArray.Count.Should().Be(1);

            // The patch operation added should be a "replace" operation.
            JToken jObject = jArray.First;

            jObject.Value <string>(Op).Should().Be(Replace);

            // The value should have a "$metadata" : {} mapping.
            JObject patchValue = jObject.Value <JObject>(Value);

            patchValue[Metadata].Should().NotBeNull();
            patchValue[Metadata].Should().BeEmpty();
        }
        public async void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
        {
            // After this is deployed, you need to turn the Managed Identity Status to "On",
            // Grab Object Id of the function and assigned "Azure Digital Twins Owner (Preview)" role
            // to this function identity in order for this function to be authorized on ADT APIs.

            //Authenticate with Digital Twins
            var credentials           = new DefaultAzureCredential();
            DigitalTwinsClient client = new DigitalTwinsClient(
                new Uri(adtServiceUrl), credentials, new DigitalTwinsClientOptions
            {
                Transport = new HttpClientTransport(httpClient)
            });

            log.LogInformation($"ADT service client connection created.");

            if (eventGridEvent != null && eventGridEvent.Data != null)
            {
                log.LogInformation(eventGridEvent.Data.ToString());

                // Reading deviceId and temperature for IoT Hub JSON
                JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());
                string  deviceId      = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"];
                var     temperature   = deviceMessage["body"]["Temperature"];

                log.LogInformation($"Device:{deviceId} Temperature is:{temperature}");

                //Update twin using device temperature
                var uou = new UpdateOperationsUtility();
                uou.AppendReplaceOp("/Temperature", temperature.Value <double>());
                await client.UpdateDigitalTwinAsync(deviceId, uou.Serialize());
            }
        }
        public static string GetWifiComponentUpdatePayload()
        {
            var uou = new UpdateOperationsUtility();

            uou.AppendReplaceOp("/Network", "New Network");
            return(RemoveNewLines(uou.Serialize()));
        }
        private async Task UpdateDigitalTwinComponentPropertyAsync()
        {
            // Choose a random value to assign to the targetTemperature property in thermostat1 component
            int desiredTargetTemperature = Random.Next(0, 100);

            const string targetTemperaturePropertyName = "targetTemperature";
            var          updateOperation = new UpdateOperationsUtility();

            // First let's take a look at when the property was updated and what was it set to.
            HttpOperationResponse <TemperatureControllerTwin, DigitalTwinGetHeaders> getDigitalTwinResponse = await _digitalTwinClient
                                                                                                              .GetDigitalTwinAsync <TemperatureControllerTwin>(_digitalTwinId);

            ThermostatTwin thermostat1 = getDigitalTwinResponse.Body.Thermostat1;

            if (thermostat1 != null)
            {
                // Thermostat1 is present in the TemperatureController twin. We can add/replace the component-level property "targetTemperature"
                double?currentComponentTargetTemperature = getDigitalTwinResponse.Body.Thermostat1.TargetTemperature;
                if (currentComponentTargetTemperature != null)
                {
                    DateTimeOffset targetTemperatureDesiredLastUpdateTime = getDigitalTwinResponse.Body.Thermostat1.Metadata.TargetTemperature.LastUpdateTime;
                    _logger.LogDebug($"The property {targetTemperaturePropertyName} under component {Thermostat1Component} was last updated on `" +
                                     $"{targetTemperatureDesiredLastUpdateTime.ToLocalTime()} `" +
                                     $" with a value of {getDigitalTwinResponse.Body.Thermostat1.Metadata.TargetTemperature.DesiredValue}.");

                    // The property path to be replaced should be prepended with a '/'
                    updateOperation.AppendReplacePropertyOp($"/{Thermostat1Component}/{targetTemperaturePropertyName}", desiredTargetTemperature);
                }
                else
                {
                    _logger.LogDebug($"The property {targetTemperaturePropertyName} under component {Thermostat1Component} `" +
                                     $"was never set on the {_digitalTwinId} digital twin.");

                    // The property path to be added should be prepended with a '/'
                    updateOperation.AppendAddPropertyOp($"/{Thermostat1Component}/{targetTemperaturePropertyName}", desiredTargetTemperature);
                }
            }
            else
            {
                // Thermostat1 is not present in the TemperatureController twin. We will add the component
                var componentProperty = new Dictionary <string, object> {
                    { targetTemperaturePropertyName, desiredTargetTemperature }, { "$metadata", new object() }
                };
                _logger.LogDebug($"The component {Thermostat1Component} does not exist on the {_digitalTwinId} digital twin.");

                // The property path to be replaced should be prepended with a '/'
                updateOperation.AppendAddComponentOp($"/{Thermostat1Component}", componentProperty);
            }

            _logger.LogDebug($"Update the {targetTemperaturePropertyName} property under component {Thermostat1Component} on the {_digitalTwinId} `" +
                             $"digital twin to {desiredTargetTemperature}.");
            HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> updateDigitalTwinResponse = await _digitalTwinClient
                                                                                               .UpdateDigitalTwinAsync(_digitalTwinId, updateOperation.Serialize());

            _logger.LogDebug($"Update {_digitalTwinId} digital twin response: {updateDigitalTwinResponse.Response.StatusCode}.");

            // Print the TemperatureController digital twin
            await GetAndPrintDigitalTwinAsync <TemperatureControllerTwin>();
        }
        public static async Task Run(
            [EventHubTrigger("deviceevents", Connection = "EVENTHUB_CONNECTIONSTRING")] EventData[] events, ILogger log)
        {
            // After this is deployed, you need to turn the Managed Identity Status to "On",
            // Grab Object Id of the function and assigned "Azure Digital Twins Owner (Preview)" role
            // to this function identity in order for this function to be authorized on ADT APIs.
            if (adtInstanceUrl == null)
            {
                log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
            }

            var exceptions = new List <Exception>();

            foreach (EventData eventData in events)
            {
                try
                {
                    // Get message body
                    string messageBody = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);

                    // Create Digital Twin client
                    var cred   = new ManagedIdentityCredential("https://digitaltwins.azure.net");
                    var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions {
                        Transport = new HttpClientTransport(httpClient)
                    });

                    // Reading Device ID from message headers
                    JObject jbody    = (JObject)JsonConvert.DeserializeObject(messageBody);
                    string  deviceId = eventData.SystemProperties["iothub-connection-device-id"].ToString();

                    string dtId = deviceId; // simple mapping

                    // Extracting temperature from device telemetry
                    double temperature = Convert.ToDouble(jbody["Temperature"].ToString());

                    // Update device Temperature property
                    UpdateOperationsUtility uou = new UpdateOperationsUtility();
                    uou.AppendAddOp("/Temperature", temperature);
                    await client.UpdateDigitalTwinAsync(dtId, uou.Serialize());

                    log.LogInformation($"Updated Temperature of device Twin '{dtId}' to: {temperature}");
                }
                catch (Exception e)
                {
                    // We need to keep processing the rest of the batch - capture this exception and continue.
                    exceptions.Add(e);
                }
            }

            if (exceptions.Count > 1)
            {
                throw new AggregateException(exceptions);
            }

            if (exceptions.Count == 1)
            {
                throw exceptions.Single();
            }
        }
        public override async Task HandleMessageAsync(DeviceTelemetryMessage requestBody, RequestDetails requestDetails, RequestMessageHeaders headers, IExtensionGatewayClient client, ILogger log)
        {
            //write telemetry to statestore
            await client.PutDeviceTelemetryAsync(requestDetails.DeviceName, requestBody);

            // Create a secret client using the DefaultAzureCredential

            DefaultAzureCredential cred  = new DefaultAzureCredential();
            DigitalTwinsClient     dtcli = new DigitalTwinsClient(new Uri("https://mobility-vss.api.wus2.digitaltwins.azure.net"), cred);

            DTUnit du = JsonSerializer.Deserialize <DTUnit>((string)requestBody.Payload);

            var updateOps = new UpdateOperationsUtility();

            if (du.type == "boolean")
            {
                updateOps.AppendAddOp(du.path, bool.Parse(du.value));
            }
            else if ((du.type == "date") || (du.type == "datetime") || (du.type == "time"))
            {
                updateOps.AppendAddOp(du.path, DateTime.Parse(du.value));
            }
            else if (du.type == "double")
            {
                updateOps.AppendAddOp(du.path, double.Parse(du.value));
            }
            else if (du.type == "float")
            {
                updateOps.AppendAddOp(du.path, float.Parse(du.value));
            }
            else if (du.type == "integer")
            {
                updateOps.AppendAddOp(du.path, int.Parse(du.value));
            }
            else if (du.type == "long")
            {
                updateOps.AppendAddOp(du.path, long.Parse(du.value));
            }
            else
            {
                updateOps.AppendAddOp(du.path, du.value);
            }

            string patchPayload = updateOps.Serialize();
            await dtcli.UpdateDigitalTwinAsync(du.dtID, patchPayload);

            // send stuff to the analytics pipeline
            var telemetryItem = new
            {
                VehicleId     = requestDetails.VehicleId,
                TelemetryName = requestBody.TelemetryName,
                Time          = requestBody.Time,
                Payload       = patchPayload
            };

            await client.SendToAnalyticsPipeline(telemetryItem);
        }
        public static string GetRoomTwinUpdatePayload()
        {
            var uou = new UpdateOperationsUtility();

            uou.AppendAddOp("/Humidity", 30);
            uou.AppendReplaceOp("/Temperature", 70);
            uou.AppendRemoveOp("/EmployeeId");
            return(RemoveNewLines(uou.Serialize()));
        }
        private static string generatePatchForTurbine(PowerValues powerValues)
        {
            UpdateOperationsUtility uou = new UpdateOperationsUtility();

            uou.AppendReplaceOp("/powerObserved", powerValues.powerObserved);
            uou.AppendReplaceOp("/powerPM", powerValues.powerPM);
            uou.AppendReplaceOp("/powerDM", powerValues.powerDM);

            return(uou.Serialize());
        }
        public static async Task Run(
            [EventHubTrigger("deviceevents", Connection = "EVENTHUB_CONNECTIONSTRING")] EventData[] events, ILogger log)
        {
            var exceptions = new List <Exception>();

            foreach (EventData eventData in events)
            {
                try
                {
                    // Get message body
                    string messageBody = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);

                    // Create Digital Twin client
                    var cred   = new ManagedIdentityCredential(adtAppId);
                    var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions {
                        Transport = new HttpClientTransport(httpClient)
                    });

                    // Reading Device ID from message headers
                    JObject jbody    = (JObject)JsonConvert.DeserializeObject(messageBody);
                    string  deviceId = eventData.SystemProperties["iothub-connection-device-id"].ToString();

                    string dtId = deviceId; // simple mapping

                    // Extracting temperature from device telemetry
                    double temperature = Convert.ToDouble(jbody["Temperature"].ToString());

                    // Update device Temperature property
                    UpdateOperationsUtility uou = new UpdateOperationsUtility();
                    uou.AppendAddOp("/Temperature", temperature);
                    await client.UpdateDigitalTwinAsync(dtId, uou.Serialize());

                    log.LogInformation($"Updated Temperature of device Twin '{dtId}' to: {temperature}");
                }
                catch (Exception e)
                {
                    // We need to keep processing the rest of the batch - capture this exception and continue.
                    exceptions.Add(e);
                }
            }

            if (exceptions.Count > 1)
            {
                throw new AggregateException(exceptions);
            }

            if (exceptions.Count == 1)
            {
                throw exceptions.Single();
            }
        }
Ejemplo n.º 12
0
        public async Task Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
        {
            // After this is deployed, you need to turn the Managed Identity Status to "On",
            // Grab Object Id of the function and assigned "Azure Digital Twins Owner (Preview)" role
            // to this function identity in order for this function to be authorized on ADT APIs.
            if (adtInstanceUrl == null)
            {
                log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
            }

            try
            {
                //Authenticate with Digital Twins
                ManagedIdentityCredential cred   = new ManagedIdentityCredential("https://digitaltwins.azure.net");
                DigitalTwinsClient        client = new DigitalTwinsClient(new Uri(adtInstanceUrl),
                                                                          cred,
                                                                          new DigitalTwinsClientOptions
                {
                    Transport = new HttpClientTransport(httpClient)
                });

                if (eventGridEvent != null && eventGridEvent.Data != null)
                {
                    log.LogInformation(eventGridEvent.Data.ToString());

                    JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());
                    byte[]  body_byte     = System.Convert.FromBase64String(deviceMessage["body"].ToString());
                    var     body_value    = System.Text.ASCIIEncoding.ASCII.GetString(body_byte);
                    var     body_json     = (JObject)JsonConvert.DeserializeObject(body_value);

                    //log.LogInformation($"Body {body_json}");

                    log.LogInformation(deviceMessage.ToString());
                    string deviceId    = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"];
                    var    temperature = body_json["temperature_hts221"];
                    var    humidity    = body_json["humidity"];

                    log.LogInformation($"Device:{deviceId} Temperature is:{temperature} Humidity is:{humidity}");

                    //Update twin using device temperature
                    var uou = new UpdateOperationsUtility();
                    uou.AppendReplaceOp("/Temperature", temperature.Value <double>());
                    uou.AppendReplaceOp("/HumidityLevel", humidity.Value <double>());
                    await client.UpdateDigitalTwinAsync(deviceId, uou.Serialize());
                }
            }
            catch (Exception e)
            {
                log.LogError($"Error in ingest function: {e.Message}");
            }
        }
        public void UpdateOperationsUtility_BuildAdd()
        {
            // arrange

            const string addOp     = "add";
            const string replaceOp = "replace";
            const string removeOp  = "remove";

            const string addPath      = "/addComponentPath123";
            const string addValue     = "value123";
            const string replacePath  = "/replaceComponentPath123";
            const string replaceValue = "value456";
            const string removePath   = "/removeComponentPath123";

            var dtUpdateUtility = new UpdateOperationsUtility();

            dtUpdateUtility.AppendAddOp(addPath, addValue);
            dtUpdateUtility.AppendReplaceOp(replacePath, replaceValue);
            dtUpdateUtility.AppendRemoveOp(removePath);

            // act
            string actual = dtUpdateUtility.Serialize();

            // assert

            JsonDocument parsed = JsonDocument.Parse(actual);

            parsed.RootElement.ValueKind.Should().Be(JsonValueKind.Array, "operations should be nested in an array");
            parsed.RootElement.GetArrayLength().Should().Be(3, "three operations were included");

            JsonElement addElement = parsed.RootElement[0];

            addElement.GetProperty("op").GetString().Should().Be(addOp);
            addElement.GetProperty("path").GetString().Should().Be(addPath);
            addElement.GetProperty("value").GetString().Should().Be(addValue);

            JsonElement replaceElement = parsed.RootElement[1];

            replaceElement.GetProperty("op").GetString().Should().Be(replaceOp);
            replaceElement.GetProperty("path").GetString().Should().Be(replacePath);
            replaceElement.GetProperty("value").GetString().Should().Be(replaceValue);

            JsonElement removeElement = parsed.RootElement[2];

            removeElement.GetProperty("op").GetString().Should().Be(removeOp);
            removeElement.GetProperty("path").GetString().Should().Be(removePath);
            removeElement.TryGetProperty("value", out _).Should().BeFalse();
        }
        private static string generatePatchForSensor(WTInfo info, TemperatureValues tempValues)
        {
            UpdateOperationsUtility uou = new UpdateOperationsUtility();

            uou.AppendReplaceOp("/blade1PitchAngle", info.Blade1PitchPosition);
            uou.AppendReplaceOp("/blade2PitchAngle", info.Blade2PitchPosition);
            uou.AppendReplaceOp("/blade3PitchAngle", info.Blade3PitchPosition);
            uou.AppendReplaceOp("/yawPosition", info.YawPosition);
            uou.AppendReplaceOp("/windDirection", info.WindDir);
            uou.AppendReplaceOp("/windSpeed", info.WindSpeed);
            uou.AppendReplaceOp("/temperatureNacelle", tempValues.nacelle);
            uou.AppendReplaceOp("/temperatureGenerator", tempValues.generator);
            uou.AppendReplaceOp("/temperatureGearBox", tempValues.gearBox);

            return(uou.Serialize());
        }
        public static async Task UpdateTwinPropertyAsync(DigitalTwinsClient client, string twinId, string propertyPath, object value, ILogger log)
        {
            // If the twin does not exist, this will log an error
            try
            {
                var uou = new UpdateOperationsUtility();
                uou.AppendReplaceOp(propertyPath, value);
                string patchPayload = uou.Serialize();
                log.LogInformation($"UpdateTwinPropertyAsync sending {patchPayload}");

                await client.UpdateDigitalTwinAsync(twinId, patchPayload);
            }
            catch (RequestFailedException exc)
            {
                log.LogInformation($"*** Error:{exc.Status}/{exc.Message}");
            }
        }
        private async Task UpdateCurrentTemperaturePropertyAsync()
        {
            // Choose a random value to assign to the currentTemperature property
            int currentTemperature = Random.Next(0, 100);

            const string currentTemperaturePropertyName = "currentTemperature";
            var          updateOperation = new UpdateOperationsUtility();

            // First, add the property to the digital twin
            updateOperation.AppendAddPropertyOp($"/{currentTemperaturePropertyName}", currentTemperature);
            _logger.LogDebug($"Add the {currentTemperaturePropertyName} property on the {_digitalTwinId} digital twin " +
                             $"with a value of {currentTemperature}.");
            HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> addPropertyToDigitalTwinResponse = await _digitalTwinClient
                                                                                                      .UpdateDigitalTwinAsync(_digitalTwinId, updateOperation.Serialize());

            _logger.LogDebug($"Update {_digitalTwinId} digital twin response: {addPropertyToDigitalTwinResponse.Response.StatusCode}.");

            // Print the Thermostat digital twin
            await GetAndPrintDigitalTwinAsync <ThermostatTwin>();

            // Second, replace the property to a different value
            int newCurrentTemperature = Random.Next(0, 100);

            updateOperation.AppendReplacePropertyOp($"/{currentTemperaturePropertyName}", newCurrentTemperature);
            _logger.LogDebug($"Replace the {currentTemperaturePropertyName} property on the {_digitalTwinId} digital twin " +
                             $"with a value of {newCurrentTemperature}.");
            HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> replacePropertyInDigitalTwinResponse = await _digitalTwinClient
                                                                                                          .UpdateDigitalTwinAsync(_digitalTwinId, updateOperation.Serialize());

            _logger.LogDebug($"Update {_digitalTwinId} digital twin response: {replacePropertyInDigitalTwinResponse.Response.StatusCode}.");

            // Print the Thermostat digital twin
            await GetAndPrintDigitalTwinAsync <ThermostatTwin>();

            // Third, remove the currentTemperature property
            updateOperation.AppendRemoveOp($"/{currentTemperaturePropertyName}");
            _logger.LogDebug($"Remove the {currentTemperaturePropertyName} property on the {_digitalTwinId} digital twin.");
            HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> removePropertyInDigitalTwinResponse = await _digitalTwinClient
                                                                                                         .UpdateDigitalTwinAsync(_digitalTwinId, updateOperation.Serialize());

            _logger.LogDebug($"Update {_digitalTwinId} digital twin response: {removePropertyInDigitalTwinResponse.Response.StatusCode}.");

            // Print the Thermostat digital twin
            await GetAndPrintDigitalTwinAsync <ThermostatTwin>();
        }
Ejemplo n.º 17
0
        public void UpdateUtilityAppendsRemoveOp()
        {
            var    op   = new UpdateOperationsUtility();
            string path = "testPath";

            op.AppendRemoveOp(path);
            string operations = op.Serialize();

            // There should be a single operation added.
            var jArray = JArray.Parse(operations);

            jArray.Count.Should().Be(1);

            // The patch operation added should be a "remove" operation.
            JToken jObject = jArray.First;

            jObject.Value <string>(Op).Should().Be(Remove);
        }
Ejemplo n.º 18
0
        public void UpdateUtilityAppendsAddPropertyOp()
        {
            var    op    = new UpdateOperationsUtility();
            string path  = "testPath";
            int    value = 10;

            op.AppendAddPropertyOp(path, value);
            string operations = op.Serialize();

            // There should be a single operation added.
            var jArray = JArray.Parse(operations);

            jArray.Count.Should().Be(1);

            // The patch operation added should be an "add" operation.
            JToken jObject = jArray.First;

            jObject.Value <string>(Op).Should().Be(Add);
        }
        private async Task UpdateTargetTemperaturePropertyAsync()
        {
            const string targetTemperaturePropertyName = "targetTemperature";
            var          updateOperation = new UpdateOperationsUtility();

            // Choose a random value to assign to the targetTemperature property
            int desiredTargetTemperature = Random.Next(0, 100);

            // First let's take a look at when the property was updated and what was it set to.
            HttpOperationResponse <ThermostatTwin, DigitalTwinGetHeaders> getDigitalTwinResponse = await _digitalTwinClient
                                                                                                   .GetDigitalTwinAsync <ThermostatTwin>(_digitalTwinId);

            double?currentTargetTemperature = getDigitalTwinResponse.Body.TargetTemperature;

            if (currentTargetTemperature != null)
            {
                DateTimeOffset targetTemperatureDesiredLastUpdateTime = getDigitalTwinResponse.Body.Metadata.TargetTemperature.LastUpdateTime;
                _logger.LogDebug($"The property {targetTemperaturePropertyName} was last updated on " +
                                 $"{targetTemperatureDesiredLastUpdateTime.ToLocalTime()} `" +
                                 $" with a value of {getDigitalTwinResponse.Body.Metadata.TargetTemperature.DesiredValue}.");

                // The property path to be replaced should be prepended with a '/'
                updateOperation.AppendReplacePropertyOp($"/{targetTemperaturePropertyName}", desiredTargetTemperature);
            }
            else
            {
                _logger.LogDebug($"The property {targetTemperaturePropertyName} was never set on the ${_digitalTwinId} digital twin.");

                // The property path to be added should be prepended with a '/'
                updateOperation.AppendAddPropertyOp($"/{targetTemperaturePropertyName}", desiredTargetTemperature);
            }

            _logger.LogDebug($"Update the {targetTemperaturePropertyName} property on the " +
                             $"{_digitalTwinId} digital twin to {desiredTargetTemperature}.");
            HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> updateDigitalTwinResponse = await _digitalTwinClient
                                                                                               .UpdateDigitalTwinAsync(_digitalTwinId, updateOperation.Serialize());

            _logger.LogDebug($"Update {_digitalTwinId} digital twin response: {updateDigitalTwinResponse.Response.StatusCode}.");

            // Print the Thermostat digital twin
            await GetAndPrintDigitalTwinAsync <ThermostatTwin>();
        }
Ejemplo n.º 20
0
        private async Task UpdateDigitalTwinProperty(DigitalTwinsClient client, string deviceId, JToken body, string propertyName)
        {
            var propertyToken = body[propertyName];

            if (propertyToken != null)
            {
                if (Constants.Telemetries.Contains(propertyName.ToUpper()))
                {
                    var data = new Dictionary <string, double>();
                    data.Add(propertyName, propertyToken.Value <double>());
                    await client.PublishTelemetryAsync(deviceId, JsonConvert.SerializeObject(data));
                }
                else
                {
                    // Update twin using device property
                    var uou = new UpdateOperationsUtility();
                    uou.AppendReplaceOp($"/{propertyName}", propertyToken.Value <double>());
                    await client.UpdateDigitalTwinAsync(deviceId, uou.Serialize());
                }
            }
        }
        private static void GetPatchPayload(string jsonInput, ref string dtid, ref string patchpayload)
        {
            var    updateOps = new UpdateOperationsUtility();
            DTUnit du        = JsonSerializer.Deserialize <DTUnit>(jsonInput);

            dtid = du.dtID;

            if (du.type == "boolean")
            {
                updateOps.AppendAddOp(du.path, bool.Parse(du.value));
            }
            else if ((du.type == "date") || (du.type == "datetime") || (du.type == "time"))
            {
                updateOps.AppendAddOp(du.path, DateTime.Parse(du.value));
            }
            else if (du.type == "double")
            {
                updateOps.AppendAddOp(du.path, double.Parse(du.value));
            }
            else if (du.type == "float")
            {
                updateOps.AppendAddOp(du.path, float.Parse(du.value));
            }
            else if (du.type == "integer")
            {
                updateOps.AppendAddOp(du.path, int.Parse(du.value));
            }
            else if (du.type == "long")
            {
                updateOps.AppendAddOp(du.path, long.Parse(du.value));
            }
            else
            {
                updateOps.AppendAddOp(du.path, du.value);
            }

            patchpayload = updateOps.Serialize();
        }
Ejemplo n.º 22
0
        public async void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
        {
            if (adtInstanceUrl == null)
            {
                log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
            }

            try
            {
                //Authenticate with Digital Twins

                ManagedIdentityCredential cred   = new ManagedIdentityCredential("https://digital-twin-demo-jc.api.wcus.digitaltwins.azure.net");
                DigitalTwinsClient        client = new DigitalTwinsClient(
                    new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions
                {
                    Transport = new HttpClientTransport(httpClient)
                });
                log.LogInformation($"ADT service client connection created.");

                if (eventGridEvent != null && eventGridEvent.Data != null)
                {
                    log.LogInformation(eventGridEvent.Data.ToString());

                    // Reading deviceId, temperature, humidity, pressure, magnetometer, accelerometer and gyroscope for IoT Hub JSON

                    JObject deviceMessage   = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());
                    string  deviceId        = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"];
                    byte[]  body            = System.Convert.FromBase64String(deviceMessage["body"].ToString());
                    var     value           = System.Text.ASCIIEncoding.ASCII.GetString(body);
                    var     bodyProperty    = (JObject)JsonConvert.DeserializeObject(value);
                    var     temperature     = bodyProperty["temperature"];
                    var     humidity        = bodyProperty["humidity"];
                    var     pressure        = bodyProperty["pressure"];
                    var     magnetometer_x  = bodyProperty["magnetometer_x"];
                    var     magnetometer_y  = bodyProperty["magnetometer_y"];
                    var     magnetometer_z  = bodyProperty["magnetometer_z"];
                    var     accelerometer_x = bodyProperty["accelerometer_x"];
                    var     accelerometer_y = bodyProperty["accelerometer_y"];
                    var     accelerometer_z = bodyProperty["accelerometer_z"];
                    var     gyroscope_x     = bodyProperty["gyroscope_x"];
                    var     gyroscope_y     = bodyProperty["gyroscope_y"];
                    var     gyroscope_z     = bodyProperty["gyroscope_z"];

                    log.LogInformation($"Device:{deviceId} Temperature is: {temperature}");

                    //note: AppendReplaceOp only works if model properties are instantiated when twin created.

                    var uou = new UpdateOperationsUtility();

                    if (temperature != null) //accounting for null values from I2C bus on MXChip dev kits
                    {
                        uou.AppendAddOp("/temperature", temperature.Value <double>());
                    }
                    else
                    {
                        temperature = -1000;
                        uou.AppendAddOp("/temperature", temperature.Value <double>());
                    }

                    if (humidity != null)
                    {
                        uou.AppendAddOp("/humidity", humidity.Value <double>());
                    }
                    else
                    {
                        humidity = -1000;
                        uou.AppendAddOp("/humidity", humidity.Value <double>());
                    }

                    if (pressure != null)
                    {
                        uou.AppendAddOp("/pressure", pressure.Value <double>());
                    }
                    else
                    {
                        pressure = -1000;
                        uou.AppendAddOp("/pressure", pressure.Value <double>());
                    }

                    if (magnetometer_x != null)
                    {
                        uou.AppendAddOp("/magnetometer_x", magnetometer_x.Value <double>());
                    }
                    else
                    {
                        magnetometer_x = -1000;
                        uou.AppendAddOp("/magnetometer_x", magnetometer_x.Value <double>());
                    }

                    if (magnetometer_y != null)
                    {
                        uou.AppendAddOp("/magnetometer_y", magnetometer_y.Value <double>());
                    }
                    else
                    {
                        magnetometer_y = -1000;
                        uou.AppendAddOp("/magnetometer_y", magnetometer_y.Value <double>());
                    }

                    if (magnetometer_z != null)
                    {
                        uou.AppendAddOp("/magnetometer_z", magnetometer_z.Value <double>());
                    }
                    else
                    {
                        magnetometer_z = -1000;
                        uou.AppendAddOp("/magnetometer_z", magnetometer_z.Value <double>());
                    }

                    if (accelerometer_x != null)
                    {
                        uou.AppendAddOp("/accelerometer_x", accelerometer_x.Value <double>());
                    }
                    else
                    {
                        accelerometer_x = -1000;
                        uou.AppendAddOp("/accelerometer_x", accelerometer_x.Value <double>());
                    }

                    if (accelerometer_y != null)
                    {
                        uou.AppendAddOp("/accelerometer_y", accelerometer_y.Value <double>());
                    }
                    else
                    {
                        accelerometer_y = -1000;
                        uou.AppendAddOp("/accelerometer_y", accelerometer_y.Value <double>());
                    }

                    if (accelerometer_z != null)
                    {
                        uou.AppendAddOp("/accelerometer_z", accelerometer_z.Value <double>());
                    }
                    else
                    {
                        accelerometer_z = -1000;
                        uou.AppendAddOp("/accelerometer_z", accelerometer_z.Value <double>());
                    }

                    if (gyroscope_x != null)
                    {
                        uou.AppendAddOp("/gyroscope_x", gyroscope_x.Value <double>());
                    }
                    else
                    {
                        gyroscope_x = -1000;
                        uou.AppendAddOp("/gyroscope_x", gyroscope_x.Value <double>());
                    }

                    if (gyroscope_y != null)
                    {
                        uou.AppendAddOp("/gyroscope_y", gyroscope_y.Value <double>());
                    }
                    else
                    {
                        gyroscope_y = -1000;
                        uou.AppendAddOp("/gyroscope_y", gyroscope_y.Value <double>());
                    }

                    if (gyroscope_z != null)
                    {
                        uou.AppendAddOp("/gyroscope_z", gyroscope_z.Value <double>());
                    }
                    else
                    {
                        gyroscope_z = -1000;
                        uou.AppendAddOp("/gyroscope_z", gyroscope_z.Value <double>());
                    }

                    await client.UpdateDigitalTwinAsync(deviceId, uou.Serialize());

                    log.LogInformation($"Device:{deviceId} Pressure is: {pressure}");
                }
            }
            catch (Exception e)
            {
                log.LogError($"Error in ingest function: {e.Message}");
            }
        }
Ejemplo n.º 23
0
        public async static void Run([EventGridTrigger] EventGridEvent ev, ILogger log)
        {
            if (adtInstanceUrl == null)
            {
                log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
            }
            try
            {
                // Authenticate with Digital Twins

                ManagedIdentityCredential cred   = new ManagedIdentityCredential("https://digitaltwins.azure.net");
                DigitalTwinsClient        client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions {
                    Transport = new HttpClientTransport(httpClient)
                });
                log.LogInformation("ADT service client connection created.");

                if (ev != null && ev.Data != null)
                {
                    // Extract JSON body from event

                    JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(ev.Data.ToString());
                    byte[]  data          = System.Convert.FromBase64String((string)deviceMessage ["body"]);
                    JObject body          = (JObject)JsonConvert.DeserializeObject(System.Text.ASCIIEncoding.ASCII.GetString(data));

                    // Extract device twin id from message and digital twin id from system properties

                    string deviceId = (string)deviceMessage ["systemProperties"]["iothub-connection-device-id"];
                    string twinId   = (string)body ["twin_id"];
                    log.LogInformation($"Routing from device_id: {deviceId}");
                    log.LogInformation($"Routing to twin_id: {twinId}");

                    // Iterate set of readings and create change set for twin

                    JObject readings = (JObject)body ["readings"];
                    var     uou      = new UpdateOperationsUtility();
                    foreach (var reading in readings)
                    {
                        string type  = (string)reading.Value ["type"];
                        string key   = (string)reading.Key;
                        var    value = reading.Value ["value"];

                        log.LogInformation($"key: {key} value: {value} type: {type}");

                        switch (type.ToLower())
                        {
                        case "bool":
                            uou.AppendReplaceOp($"/{key}", value.Value <bool>());
                            break;

                        case "int8":
                            uou.AppendReplaceOp($"/{key}", value.Value <SByte>());
                            break;

                        case "int16":
                            uou.AppendReplaceOp($"/{key}", value.Value <Int16>());
                            break;

                        case "int32":
                            uou.AppendReplaceOp($"/{key}", value.Value <Int32>());
                            break;

                        case "uint8":
                            uou.AppendReplaceOp($"/{key}", value.Value <Byte>());
                            break;

                        case "uint16":
                            uou.AppendReplaceOp($"/{key}", value.Value <UInt16>());
                            break;

                        case "float32":
                            uou.AppendReplaceOp($"/{key}", value.Value <float>());
                            break;

                        case "float64":
                            uou.AppendReplaceOp($"/{key}", value.Value <double>());
                            break;

                        default:
                            log.LogWarning($"{key} using {type} type isn't supported");
                            break;
                        }
                    }
                    // Update digital twin
                    string digitalTwinPatch = uou.Serialize();
                    log.LogInformation($"Updating twin: {twinId} with patch {digitalTwinPatch}");
                    await client.UpdateDigitalTwinAsync(twinId, digitalTwinPatch);
                }
            }
            catch (Exception e)
            {
                log.LogError(e.Message);
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Creates a digital twin with Component and upates Component
        /// </summary>
        public async Task RunSamplesAsync()
        {
            PrintHeader("COMPONENT SAMPLE");

            // For the purpose of this example we will create temporary models using a random model Ids.
            // We have to make sure these model Ids are unique within the DT instance.

            string componentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, DigitalTwinsClient).ConfigureAwait(false);

            string modelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, DigitalTwinsClient).ConfigureAwait(false);

            string twinId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, DigitalTwinsClient).ConfigureAwait(false);

            string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload
                                              .Replace(SamplesConstants.ComponentId, componentModelId);

            string newModelPayload = SamplesConstants.TemporaryModelPayload
                                     .Replace(SamplesConstants.ModelId, modelId)
                                     .Replace(SamplesConstants.ComponentId, componentModelId);

            // Then we create models
            await DigitalTwinsClient.CreateModelsAsync(new[] { newComponentModelPayload, newModelPayload }).ConfigureAwait(false);

            Console.WriteLine($"Successfully created models with Ids: {componentModelId}, {modelId}");

            // Create digital twin with Component payload
            string twinPayload = SamplesConstants.TemporaryTwinPayload
                                 .Replace(SamplesConstants.ModelId, modelId)
                                 .Replace(SamplesConstants.ComponentId, componentModelId);

            await DigitalTwinsClient.CreateDigitalTwinAsync(twinId, twinPayload).ConfigureAwait(false);

            Console.WriteLine($"Created digital twin {twinId}.");

            #region Snippet:DigitalTwinSampleUpdateComponent

            // Update Component with replacing property value
            string propertyPath = "/ComponentProp1";
            string propValue    = "New Value";

            var componentUpdateUtility = new UpdateOperationsUtility();
            componentUpdateUtility.AppendReplaceOp(propertyPath, propValue);

            Response <string> response = await DigitalTwinsClient.UpdateComponentAsync(twinId, SamplesConstants.ComponentPath, componentUpdateUtility.Serialize());

            #endregion Snippet:DigitalTwinSampleUpdateComponent

            Console.WriteLine($"Updated component for digital twin {twinId}. Update response status: {response.GetRawResponse().Status}");

            // Get Component

            #region Snippet:DigitalTwinSampleGetComponent

            response = await DigitalTwinsClient.GetComponentAsync(twinId, SamplesConstants.ComponentPath).ConfigureAwait(false);

            #endregion Snippet:DigitalTwinSampleGetComponent

            Console.WriteLine($"Get component for digital twin: \n{response.Value}. Get response status: {response.GetRawResponse().Status}");

            // Now delete a Twin
            await DigitalTwinsClient.DeleteDigitalTwinAsync(twinId).ConfigureAwait(false);

            // Delete models
            try
            {
                await DigitalTwinsClient.DeleteModelAsync(modelId).ConfigureAwait(false);

                await DigitalTwinsClient.DeleteModelAsync(componentModelId).ConfigureAwait(false);
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"Failed to delete models due to {ex}");
            }
        }
        public async Task DigitalTwinWithComponentOperationsAsync()
        {
            // Create a new test device instance.
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);

            string deviceId = testDevice.Id;

            try
            {
                // Create a device client instance over Mqtt, initializing it with the "TemperatureController" model which has "Thermostat" components.
                var options = new ClientOptions
                {
                    ModelId = TemperatureControllerModelId,
                };
                using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt, options);

                // Call openAsync() to open the device's connection, so that the ModelId is sent over Mqtt CONNECT packet.
                await deviceClient.OpenAsync().ConfigureAwait(false);

                // Perform operations on the digital twin.
                using var digitalTwinClient = DigitalTwinClient.CreateFromConnectionString(s_connectionString);

                // Retrieve the digital twin.
                HttpOperationResponse <TemperatureControllerTwin, DigitalTwinGetHeaders> response =
                    await digitalTwinClient.GetDigitalTwinAsync <TemperatureControllerTwin>(deviceId).ConfigureAwait(false);

                TemperatureControllerTwin twin = response.Body;
                twin.Metadata.ModelId.Should().Be(TemperatureControllerModelId);

                string componentName = "thermostat1";

                // Set callback handler for receiving twin property updates.
                await deviceClient.SetDesiredPropertyUpdateCallbackAsync((patch, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: DesiredProperty update received: {patch}, {context}");
                    return(Task.FromResult(true));
                }, deviceClient);

                // Update the property "targetTemperature" under component "thermostat1" on the digital twin.
                // NOTE: since this is the first operation on the digital twin, the component "thermostat1" doesn't exist on it yet.
                // So we will create a property patch that "adds" a component, and updates the property in it.
                string propertyName   = "targetTemperature";
                double propertyValue  = new Random().Next(0, 100);
                var    propertyValues = new Dictionary <string, object> {
                    { propertyName, propertyValue }
                };

                var ops = new UpdateOperationsUtility();
                ops.AppendAddComponentOp($"/{componentName}", propertyValues);
                string patch = ops.Serialize();
                HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> updateResponse =
                    await digitalTwinClient.UpdateDigitalTwinAsync(deviceId, patch);

                updateResponse.Response.StatusCode.Should().Be(HttpStatusCode.Accepted);

                // Set callbacks to handle command requests.
                int expectedCommandStatus = 200;

                // Set callback to handle root-level command invocation request.
                string rootCommandName = "reboot";
                await deviceClient.SetMethodHandlerAsync(rootCommandName,
                                                         (request, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: Digital twin command {request.Name} received.");
                    string payload = JsonConvert.SerializeObject(request.Name);
                    return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(payload), expectedCommandStatus)));
                },
                                                         null);

                // Invoke the root-level command "reboot" on the digital twin.
                int    delay = 1;
                string rootCommandPayload = JsonConvert.SerializeObject(delay);
                HttpOperationResponse <DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> rootCommandResponse =
                    await digitalTwinClient.InvokeCommandAsync(deviceId, rootCommandName, rootCommandPayload).ConfigureAwait(false);

                rootCommandResponse.Body.Status.Should().Be(expectedCommandStatus);
                rootCommandResponse.Body.Payload.Should().Be(JsonConvert.SerializeObject(rootCommandName));

                // Set callback to handle component-level command invocation request.
                // For a component-level command, the command name is in the format "<component-name>*<command-name>".
                string componentCommandName    = "getMaxMinReport";
                string componentCommandNamePnp = $"{componentName}*{componentCommandName}";
                await deviceClient.SetMethodHandlerAsync(componentCommandNamePnp,
                                                         (request, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: Digital twin command {request.Name} received.");
                    string payload = JsonConvert.SerializeObject(request.Name);
                    return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(payload), expectedCommandStatus)));
                },
                                                         null);

                // Invoke the command "getMaxMinReport" under component "thermostat1" on the digital twin.
                DateTimeOffset since = DateTimeOffset.Now.Subtract(TimeSpan.FromMinutes(1));
                string         componentCommandPayload = JsonConvert.SerializeObject(since);
                HttpOperationResponse <DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> componentCommandResponse =
                    await digitalTwinClient.InvokeComponentCommandAsync(deviceId, componentName, componentCommandName, componentCommandPayload).ConfigureAwait(false);

                componentCommandResponse.Body.Status.Should().Be(expectedCommandStatus);
                componentCommandResponse.Body.Payload.Should().Be(JsonConvert.SerializeObject(componentCommandNamePnp));
            }
            finally
            {
                // Delete the device.
                await testDevice.RemoveDeviceAsync().ConfigureAwait(false);
            }
        }
        public async Task DigitalTwinWithOnlyRootComponentOperationsAsync()
        {
            // Create a new test device instance.
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);

            string deviceId = testDevice.Id;

            try
            {
                // Create a device client instance over Mqtt, initializing it with the "Thermostat" model which has only a root component.
                var options = new ClientOptions
                {
                    ModelId = ThermostatModelId,
                };
                using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt, options);

                // Call openAsync() to open the device's connection, so that the ModelId is sent over Mqtt CONNECT packet.
                await deviceClient.OpenAsync().ConfigureAwait(false);

                // Perform operations on the digital twin.
                using var digitalTwinClient = DigitalTwinClient.CreateFromConnectionString(s_connectionString);

                // Retrieve the digital twin.
                HttpOperationResponse <ThermostatTwin, DigitalTwinGetHeaders> response =
                    await digitalTwinClient.GetDigitalTwinAsync <ThermostatTwin>(deviceId).ConfigureAwait(false);

                ThermostatTwin twin = response.Body;
                twin.Metadata.ModelId.Should().Be(ThermostatModelId);

                // Set callback handler for receiving root-level twin property updates.
                await deviceClient.SetDesiredPropertyUpdateCallbackAsync((patch, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithComponentOperationsAsync)}: DesiredProperty update received: {patch}, {context}");
                    return(Task.FromResult(true));
                }, deviceClient);

                // Update the root-level property "targetTemperature".
                string propertyName  = "targetTemperature";
                double propertyValue = new Random().Next(0, 100);
                var    ops           = new UpdateOperationsUtility();
                ops.AppendAddPropertyOp($"/{propertyName}", propertyValue);
                string patch = ops.Serialize();
                HttpOperationHeaderResponse <DigitalTwinUpdateHeaders> updateResponse =
                    await digitalTwinClient.UpdateDigitalTwinAsync(deviceId, patch);

                updateResponse.Response.StatusCode.Should().Be(HttpStatusCode.Accepted);

                // Set callback to handle root-level command invocation request.
                int    expectedCommandStatus = 200;
                string commandName           = "getMaxMinReport";
                await deviceClient.SetMethodHandlerAsync(commandName,
                                                         (request, context) =>
                {
                    Logger.Trace($"{nameof(DigitalTwinWithOnlyRootComponentOperationsAsync)}: Digital twin command received: {request.Name}.");
                    string payload = JsonConvert.SerializeObject(request.Name);
                    return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(payload), expectedCommandStatus)));
                },
                                                         null);

                // Invoke the root-level command "getMaxMinReport" on the digital twin.
                DateTimeOffset since   = DateTimeOffset.Now.Subtract(TimeSpan.FromMinutes(1));
                string         payload = JsonConvert.SerializeObject(since);
                HttpOperationResponse <DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> commandResponse =
                    await digitalTwinClient.InvokeCommandAsync(deviceId, commandName, payload).ConfigureAwait(false);

                commandResponse.Body.Status.Should().Be(expectedCommandStatus);
                commandResponse.Body.Payload.Should().Be(JsonConvert.SerializeObject(commandName));
            }
            finally
            {
                // Delete the device.
                await testDevice.RemoveDeviceAsync().ConfigureAwait(false);
            }
        }
        /// <summary>
        /// Creates a digital twin with Component and upates Component
        /// </summary>
        public async Task RunSamplesAsync()
        {
            PrintHeader("COMPONENT SAMPLE");

            // For the purpose of this example we will create temporary models using a random model Ids.
            // We have to make sure these model Ids are unique within the DT instance.

            string componentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, DigitalTwinsClient).ConfigureAwait(false);

            string modelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, DigitalTwinsClient).ConfigureAwait(false);

            string dtId1 = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, DigitalTwinsClient).ConfigureAwait(false);

            string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload
                                              .Replace(SamplesConstants.ComponentId, componentModelId);

            string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload
                                     .Replace(SamplesConstants.ModelId, modelId)
                                     .Replace(SamplesConstants.ComponentId, componentModelId);

            // Then we create models
            Response <IReadOnlyList <Models.ModelData> > createModelsResponse = await DigitalTwinsClient
                                                                                .CreateModelsAsync(new[] { newComponentModelPayload, newModelPayload })
                                                                                .ConfigureAwait(false);

            Console.WriteLine($"Successfully created models Ids {componentModelId} and {modelId} with response {createModelsResponse.GetRawResponse().Status}.");

            #region Snippet:DigitalTwinsSampleCreateBasicTwin

            // Create digital twin with Component payload using the BasicDigitalTwin serialization helper

            var basicDigitalTwin = new BasicDigitalTwin
            {
                Id = dtId1
            };
            basicDigitalTwin.Metadata.ModelId = modelId;
            basicDigitalTwin.CustomProperties.Add("Prop1", "Value1");
            basicDigitalTwin.CustomProperties.Add("Prop2", "Value2");

            var componentMetadata = new ModelProperties();
            componentMetadata.Metadata.ModelId = componentModelId;
            componentMetadata.CustomProperties.Add("ComponentProp1", "ComponentValue1");
            componentMetadata.CustomProperties.Add("ComponentProp2", "ComponentValue2");

            basicDigitalTwin.CustomProperties.Add("Component1", componentMetadata);

            string dt1Payload = JsonSerializer.Serialize(basicDigitalTwin);

            Response <string> createDt1Response = await DigitalTwinsClient.CreateDigitalTwinAsync(dtId1, dt1Payload).ConfigureAwait(false);

            Console.WriteLine($"Created digital twin {dtId1} with response {createDt1Response.GetRawResponse().Status}.");

            #endregion Snippet:DigitalTwinsSampleCreateBasicTwin

            #region Snippet:DigitalTwinsSampleCreateCustomTwin

            string dtId2 = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, DigitalTwinsClient).ConfigureAwait(false);

            var customDigitalTwin = new CustomDigitalTwin
            {
                Id       = dtId2,
                Metadata = new CustomDigitalTwinMetadata {
                    ModelId = modelId
                },
                Prop1      = "Prop1 val",
                Prop2      = "Prop2 val",
                Component1 = new Component1
                {
                    Metadata = new Component1Metadata {
                        ModelId = componentModelId
                    },
                    ComponentProp1 = "Component prop1 val",
                    ComponentProp2 = "Component prop2 val",
                }
            };
            string dt2Payload = JsonSerializer.Serialize(customDigitalTwin);

            Response <string> createDt2Response = await DigitalTwinsClient.CreateDigitalTwinAsync(dtId2, dt2Payload).ConfigureAwait(false);

            Console.WriteLine($"Created digital twin {dtId2} with response {createDt2Response.GetRawResponse().Status}.");

            #endregion Snippet:DigitalTwinsSampleCreateCustomTwin

            #region Snippet:DigitalTwinsSampleUpdateComponent

            // Update Component1 by replacing the property ComponentProp1 value
            var componentUpdateUtility = new UpdateOperationsUtility();
            componentUpdateUtility.AppendReplaceOp("/ComponentProp1", "Some new value");
            string updatePayload = componentUpdateUtility.Serialize();

            Response <string> response = await DigitalTwinsClient.UpdateComponentAsync(dtId1, "Component1", updatePayload);

            Console.WriteLine($"Updated component for digital twin {dtId1}. Update response status: {response.GetRawResponse().Status}");

            #endregion Snippet:DigitalTwinsSampleUpdateComponent

            // Get Component

            #region Snippet:DigitalTwinsSampleGetComponent

            response = await DigitalTwinsClient.GetComponentAsync(dtId1, SamplesConstants.ComponentPath).ConfigureAwait(false);

            Console.WriteLine($"Get component for digital twin: \n{response.Value}. Get response status: {response.GetRawResponse().Status}");

            #endregion Snippet:DigitalTwinsSampleGetComponent

            // Clean up

            try
            {
                await DigitalTwinsClient.DeleteDigitalTwinAsync(dtId1).ConfigureAwait(false);

                await DigitalTwinsClient.DeleteDigitalTwinAsync(dtId2).ConfigureAwait(false);
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"Failed to delete digital twin due to {ex}");
            }

            try
            {
                await DigitalTwinsClient.DeleteModelAsync(modelId).ConfigureAwait(false);

                await DigitalTwinsClient.DeleteModelAsync(componentModelId).ConfigureAwait(false);
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"Failed to delete models due to {ex}");
            }
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Creates a digital twin with Component and upates Component
        /// </summary>
        public async Task RunSamplesAsync(DigitalTwinsClient client)
        {
            PrintHeader("COMPONENT SAMPLE");

            // For the purpose of this example we will create temporary models using a random model Ids.
            // We have to make sure these model Ids are unique within the DT instance.

            string componentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, client);

            string modelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, client);

            string basicDtId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, client);

            string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload
                                              .Replace(SamplesConstants.ComponentId, componentModelId);

            string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload
                                     .Replace(SamplesConstants.ModelId, modelId)
                                     .Replace(SamplesConstants.ComponentId, componentModelId);

            // Then we create models
            Response <IReadOnlyList <Models.ModelData> > createModelsResponse = await client.CreateModelsAsync(
                new[]
            {
                newComponentModelPayload,
                newModelPayload
            });

            Console.WriteLine($"Created models with Ids {componentModelId} and {modelId}. Response status: {createModelsResponse.GetRawResponse().Status}.");

            #region Snippet:DigitalTwinsSampleCreateBasicTwin

            // Create digital twin with component payload using the BasicDigitalTwin serialization helper

            var basicTwin = new BasicDigitalTwin
            {
                Id = basicDtId,
                // model Id of digital twin
                Metadata         = { ModelId = modelId },
                CustomProperties =
                {
                    // digital twin properties
                    { "Prop1",          "Value1"            },
                    { "Prop2",                          987 },
                    // component
                    {
                        "Component1",
                        new ModelProperties
                        {
                            // component properties
                            CustomProperties =
                            {
                                { "ComponentProp1", "Component value 1" },
                                { "ComponentProp2",                 123 },
                            },
                        }
                    },
                },
            };

            string basicDtPayload = JsonSerializer.Serialize(basicTwin);

            Response <string> createBasicDtResponse = await client.CreateDigitalTwinAsync(basicDtId, basicDtPayload);

            Console.WriteLine($"Created digital twin with Id {basicDtId}. Response status: {createBasicDtResponse.GetRawResponse().Status}.");

            #endregion Snippet:DigitalTwinsSampleCreateBasicTwin

            // You can also get a digital twin and deserialize it into a BasicDigitalTwin.
            // It works well for basic stuff, but as you can see it gets more difficult when delving into
            // more complex properties, like components.

            #region Snippet:DigitalTwinsSampleGetBasicDigitalTwin

            Response <string> getBasicDtResponse = await client.GetDigitalTwinAsync(basicDtId);

            if (getBasicDtResponse.GetRawResponse().Status == (int)HttpStatusCode.OK)
            {
                BasicDigitalTwin basicDt = JsonSerializer.Deserialize <BasicDigitalTwin>(getBasicDtResponse.Value);

                // Must cast Component1 as a JsonElement and get its raw text in order to deserialize it as a dictionary
                string component1RawText = ((JsonElement)basicDt.CustomProperties["Component1"]).GetRawText();
                IDictionary <string, object> component1 = JsonSerializer.Deserialize <IDictionary <string, object> >(component1RawText);

                Console.WriteLine($"Retrieved and deserialized digital twin {basicDt.Id}:\n\t" +
                                  $"ETag: {basicDt.ETag}\n\t" +
                                  $"Prop1: {basicDt.CustomProperties["Prop1"]}\n\t" +
                                  $"Prop2: {basicDt.CustomProperties["Prop2"]}\n\t" +
                                  $"ComponentProp1: {component1["ComponentProp1"]}\n\t" +
                                  $"ComponentProp2: {component1["ComponentProp2"]}");
            }

            #endregion Snippet:DigitalTwinsSampleGetBasicDigitalTwin

            string customDtId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, client);

            // Alternatively, you can create your own custom data types to serialize and deserialize your digital twins.
            // By specifying your properties and types directly, it requires less code or knowledge of the type for
            // interaction.

            #region Snippet:DigitalTwinsSampleCreateCustomTwin

            var customTwin = new CustomDigitalTwin
            {
                Id         = customDtId,
                Metadata   = { ModelId = modelId },
                Prop1      = "Prop1 val",
                Prop2      = 987,
                Component1 = new Component1
                {
                    ComponentProp1 = "Component prop1 val",
                    ComponentProp2 = 123,
                }
            };
            string dt2Payload = JsonSerializer.Serialize(customTwin);

            Response <string> createCustomDtResponse = await client.CreateDigitalTwinAsync(customDtId, dt2Payload);

            Console.WriteLine($"Created digital twin with Id {customDtId}. Response status: {createCustomDtResponse.GetRawResponse().Status}.");

            #endregion Snippet:DigitalTwinsSampleCreateCustomTwin

            // Getting and deserializing a digital twin into a custom data type is extremely easy.
            // Custom types provide the best possible experience.

            #region Snippet:DigitalTwinsSampleGetCustomDigitalTwin

            Response <string> getCustomDtResponse = await client.GetDigitalTwinAsync(customDtId);

            if (getCustomDtResponse.GetRawResponse().Status == (int)HttpStatusCode.OK)
            {
                CustomDigitalTwin customDt = JsonSerializer.Deserialize <CustomDigitalTwin>(getCustomDtResponse.Value);
                Console.WriteLine($"Retrieved and deserialized digital twin {customDt.Id}:\n\t" +
                                  $"ETag: {customDt.ETag}\n\t" +
                                  $"Prop1: {customDt.Prop1}\n\t" +
                                  $"Prop2: {customDt.Prop2}\n\t" +
                                  $"ComponentProp1: {customDt.Component1.ComponentProp1}\n\t" +
                                  $"ComponentProp2: {customDt.Component1.ComponentProp2}");
            }

            #endregion Snippet:DigitalTwinsSampleGetCustomDigitalTwin

            #region Snippet:DigitalTwinsSampleUpdateComponent

            // Update Component1 by replacing the property ComponentProp1 value
            var componentUpdateUtility = new UpdateOperationsUtility();
            componentUpdateUtility.AppendReplaceOp("/ComponentProp1", "Some new value");
            string updatePayload = componentUpdateUtility.Serialize();

            Response <string> response = await client.UpdateComponentAsync(basicDtId, "Component1", updatePayload);

            Console.WriteLine($"Updated component for digital twin with Id {basicDtId}. Response status: {response.GetRawResponse().Status}");

            #endregion Snippet:DigitalTwinsSampleUpdateComponent

            // Get Component

            #region Snippet:DigitalTwinsSampleGetComponent

            response = await client.GetComponentAsync(basicDtId, SamplesConstants.ComponentPath);

            Console.WriteLine($"Retrieved component for digital twin with Id {basicDtId}. Response status: {response.GetRawResponse().Status}");

            #endregion Snippet:DigitalTwinsSampleGetComponent

            // Clean up

            try
            {
                await client.DeleteDigitalTwinAsync(basicDtId);

                await client.DeleteDigitalTwinAsync(customDtId);
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"Failed to delete digital twin due to {ex}");
            }

            try
            {
                await client.DeleteModelAsync(modelId);

                await client.DeleteModelAsync(componentModelId);
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"Failed to delete models due to {ex}");
            }
        }