/// <summary> /// Update desired properties /// </summary> /// <param name="properties"></param> public void UpdateDesiredProperties(Dictionary <string, VariantValue> properties) { lock (_lock) { if (Twin.Properties == null) { Twin.Properties = new TwinPropertiesModel(); } Twin.Properties.Desired = Merge(Twin.Properties.Desired, properties); Twin.LastActivityTime = DateTime.UtcNow; Twin.Etag = Device.Etag = Guid.NewGuid().ToString(); } if (Connection != null) { var desired = new TwinCollection(); foreach (var item in Twin.Properties.Desired) { desired[item.Key] = item.Value?.ConvertTo <object>(); } Connection.SetDesiredProperties(desired); } }
/// <summary> /// Process default settings /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="processed"></param> /// <returns></returns> private bool ProcessEdgeHostSettings(string key, dynamic value, TwinCollection processed = null) { switch (key.ToLowerInvariant()) { case TwinProperty.Connected: case TwinProperty.Type: break; case TwinProperty.SiteId: SiteId = (string)value; break; default: return(false); } if (processed != null) { processed[key] = value; } return(true); }
public static T GetPropertyValue <T>(this TwinCollection collection, string propertyName) { T result = default(T); if (collection.Contains(propertyName)) { var propertyJson = collection[propertyName] as JObject; if (propertyJson != null) { if (propertyJson.ContainsKey("value")) { var propertyValue = propertyJson["value"]; result = propertyValue.Value <T>(); } } else { result = collection[propertyName].Value; } } return(result); }
private static TwinCollection DictionaryToTwinCollection(Dictionary <string, JToken> x) { var result = new TwinCollection(); if (x != null) { foreach (KeyValuePair <string, JToken> item in x) { try { result[item.Key] = item.Value; } catch (Exception e) { Console.WriteLine(e); throw; } } } return(result); }
internal async Task GenericTwinReportedUpdateAsync(string deviceId, string sensorId, string propertyName, dynamic value) { string logPrefix = "c2dtwins".BuildLogPrefix(); try { _logger.LogDebug($"{logPrefix}::{_deviceSettings.ArtifactId}::Sending generic reported property update:: {propertyName}-{value}."); //TODO: send DTDL readable properties //https://docs.microsoft.com/en-us/azure/iot-central/core/concepts-telemetry-properties-commands TwinCollection reportedProperties; reportedProperties = new TwinCollection(); reportedProperties[propertyName] = value; await _deviceClient.UpdateReportedPropertiesAsync(reportedProperties); } catch (Exception ex) { _logger.LogError($"{logPrefix}::{_deviceSettings.ArtifactId}::ERROR::GenericTwinReportedUpdateAsync:{ex.Message}."); } }
// This method updates local state and should be called only after acquiring twinLock async Task ApplyPatchAsync(TwinCollection desiredProperties, TwinCollection patch) { try { string mergedJson = JsonEx.Merge(desiredProperties, patch, true); desiredProperties = new TwinCollection(mergedJson); Events.LogDesiredPropertiesAfterPatch(desiredProperties); if (this.CheckIfTwinSignatureIsValid(desiredProperties)) { this.desiredProperties = Option.Some(desiredProperties); await this.UpdateDeploymentConfig(desiredProperties); Events.DesiredPropertiesPatchApplied(); } } catch (Exception ex) when(!ex.IsFatal()) { this.deploymentConfigInfo = Option.Some(new DeploymentConfigInfo(desiredProperties?.Version ?? 0, ex)); Events.DesiredPropertiesPatchFailed(ex); // Update reported properties with last desired status } }
public async Task MqttTransportHandlerSendTwinPatchAsyncReturnsFailure() { // arrange var transport = CreateTransportHandlerWithMockChannel(out IChannel channel); var props = new TwinCollection(); channel .WriteAndFlushAsync(Arg.Is <Message>(msg => msg.MqttTopicName.StartsWith(twinPatchReportedTopicPrefix))) .Returns(msg => { var request = msg.Arg <Message>(); var response = new Message(); response.MqttTopicName = GetResponseTopic(request.MqttTopicName, statusFailure); transport.OnMessageReceived(response); return(TaskHelpers.CompletedTask); }); // act & assert await transport.OpenAsync(CancellationToken.None).ConfigureAwait(false); await transport.SendTwinPatchAsync(props, CancellationToken.None).ExpectedAsync <IotHubException>().ConfigureAwait(false); }
public static void CreateSupportedMethodReport(TwinCollection patch, IEnumerable <Command> commands, TwinCollection reported) { var existingMethods = new HashSet <string>(); if (reported != null && reported.Contains("SupportedMethods")) { existingMethods.UnionWith(reported.AsEnumerableFlatten() .Select(pair => pair.Key) .Where(key => key.StartsWith("SupportedMethods.", StringComparison.Ordinal)) .Select(key => key.Split('.')[1])); } var supportedMethods = new TwinCollection(); foreach (var method in commands.Where(c => c.DeliveryType == DeliveryType.Method)) { if (string.IsNullOrWhiteSpace(method.Name)) { continue; } if (method.Parameters.Any(p => string.IsNullOrWhiteSpace(p.Name) || string.IsNullOrWhiteSpace(p.Type))) { continue; } var pair = method.Serialize(); supportedMethods[pair.Key] = pair.Value; existingMethods.Remove(pair.Key); } foreach (var method in existingMethods) { supportedMethods[method] = null; } patch["SupportedMethods"] = supportedMethods; }
public async Task RunSampleAsync() { await _deviceClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChangedAsync, null).ConfigureAwait(false); Console.WriteLine("Retrieving twin..."); Twin twin = await _deviceClient.GetTwinAsync().ConfigureAwait(false); Console.WriteLine("\tInitial twin value received:"); Console.WriteLine($"\t{twin.ToJson()}"); Console.WriteLine("Sending sample start time as reported property"); TwinCollection reportedProperties = new TwinCollection(); reportedProperties["DateTimeLastAppLaunch"] = DateTime.Now; await _deviceClient.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false); Console.WriteLine("Waiting 30 seconds for IoT Hub Twin updates..."); Console.WriteLine($"Use the IoT Hub Azure Portal to change the Twin desired properties within this time."); await Task.Delay(30 * 1000); }
public async Task UpdateReportedPropertiesAsync(TwinCollection patch) { Events.UpdatingReportedProperties(); try { Option <IModuleClient> moduleClient = this.moduleConnection.GetModuleClient(); if (!moduleClient.HasValue) { Events.UpdateReportedPropertiesDeviceClientEmpty(); return; } await moduleClient.ForEachAsync(d => d.UpdateReportedPropertiesAsync(patch)); Events.UpdatedReportedProperties(); } catch (Exception e) { Events.ErrorUpdatingReportedProperties(e); throw; } }
static Task onDesiredPropertiesUpdate(TwinCollection desiredProperties, object ioTHubModuleClient) { try { Console.WriteLine("Desired property change:"); Console.WriteLine(JsonConvert.SerializeObject(desiredProperties)); if (desiredProperties["redisIPAddress"] != null) { redisIPAddress = desiredProperties["redisIPAddress"]; } if (desiredProperties["redisChannelName"] != null) { redisChannelName = desiredProperties["redisChannelName"]; } Console.WriteLine("Unsubscribing..."); UnsubscribeFromAll(); Console.WriteLine("Resubscribing..."); Subscribe(redisIPAddress, redisChannelName, ioTHubModuleClient); } 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); } Console.WriteLine("onDesiredPropertiesUpdate Complete"); return(Task.CompletedTask); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _logger.LogInformation("Start device at: {time}", DateTimeOffset.Now); var deviceClient = DeviceClient.CreateFromConnectionString(_configuration.GetConnectionString("iothub"), TransportType.Amqp); var twin = await deviceClient.GetTwinAsync(); var color = twin.Properties.Desired["color"]; Console.BackgroundColor = color; Console.Clear(); var reported = new TwinCollection(); reported["color"] = Console.BackgroundColor.ToString(); //aggiorno il il reported await deviceClient.UpdateReportedPropertiesAsync(reported); while (!stoppingToken.IsCancellationRequested) { var message = await deviceClient.ReceiveAsync(TimeSpan.FromSeconds(30)); if (message != null) { var text = System.Text.UTF8Encoding.UTF8.GetString(message.GetBytes()); var json = JsonConvert.DeserializeObject <Messaggio>(text); Console.WriteLine("Messaggio: " + json.Text); int colorText = json.ColorText; Console.ForegroundColor = (ConsoleColor)colorText; } else { await Task.Delay(2000, stoppingToken); } } }
public async Task SendSettingAsync(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] = new JObject(); reportedPropertiesEdge[eventValue.Name]["value"] = eventValue.Value; reportedPropertiesEdge[eventValue.Name]["status"] = IoTCentral_ReportedPropertyStatusCompleted; } } else { reportedPropertiesEdge[message.DataChangeMessageData.Key] = new JObject(); reportedPropertiesEdge[message.DataChangeMessageData.Key]["value"] = message.DataChangeMessageData.Value; reportedPropertiesEdge[message.DataChangeMessageData.Key]["status"] = IoTCentral_ReportedPropertyStatusCompleted; } 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); } }
private async Task _Twin_DeviceReportedPropertiesRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec) { var propName = Guid.NewGuid().ToString(); var propValue1 = Guid.NewGuid().ToString(); Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); TwinCollection props = new TwinCollection(); props[propName] = propValue1; await deviceClient.UpdateReportedPropertiesAsync(props); var deviceTwin = await deviceClient.GetTwinAsync(); Assert.AreEqual <String>(deviceTwin.Properties.Reported[propName].ToString(), propValue1); // send error command await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec)); Thread.Sleep(1000); deviceTwin = await deviceClient.GetTwinAsync(); Assert.AreEqual <String>(deviceTwin.Properties.Reported[propName].ToString(), propValue1); var propValue2 = Guid.NewGuid().ToString(); props[propName] = propValue2; await deviceClient.UpdateReportedPropertiesAsync(props); deviceTwin = await deviceClient.GetTwinAsync(); Assert.AreEqual <String>(deviceTwin.Properties.Reported[propName].ToString(), propValue2); await deviceClient.CloseAsync(); TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); }
static async Task OnDesiredPropertiesUpdated(TwinCollection desiredProperties, object userContext) { Console.WriteLine("Device Twin Update Received"); // At this point just update the configure configuration. if (desiredProperties.Contains(SendIntervalConfigKey)) { var desiredInterval = (int)desiredProperties[SendIntervalConfigKey]; Console.WriteLine("Updating Send Interval to " + desiredInterval.ToString()); messageDelay = TimeSpan.FromMilliseconds((int)desiredProperties[SendIntervalConfigKey]); } if (desiredProperties.Contains(EventCountConfigKey)) { var desiredCount = (int)desiredProperties[EventCountConfigKey]; Console.WriteLine("Updating Event Count to " + desiredCount.ToString()); eventCount = (int)desiredProperties[EventCountConfigKey]; } if (desiredProperties.Contains(SendDataConfigKey)) { bool desiredSendDataValue = (bool)desiredProperties[SendDataConfigKey]; if (desiredSendDataValue != sendData && !desiredSendDataValue) { Console.WriteLine("Turning off Send Data. Change twin configuration to start sending again."); } sendData = desiredSendDataValue; } var settings = new TwinCollection(); settings["SendData"] = sendData; settings["SendInterval"] = messageDelay.TotalMilliseconds; settings["EventCount"] = eventCount; reportedProperties["settings"] = settings; await moduleClient.UpdateReportedPropertiesAsync(reportedProperties); }
private async Task OnDesiredPropertyChangedAsync(TwinCollection desiredProperties, object userContext) { // callback when Desired Property (settings) is changed/updated by Cloud/Backend Console.WriteLine("\r\nDesired property (Settings) changed:"); Console.WriteLine($"{desiredProperties.ToJson(Newtonsoft.Json.Formatting.Indented)}"); // IoT Central expects the following payloads in Reported Property (as a response and communicate synchronization status) if (desiredProperties.Contains("isCelsius") && desiredProperties["isCelsius"]["value"] != null) { _bCelsius = desiredProperties["isCelsius"]["value"]; // update reported properties to keep UI and device state in synch TwinCollection twinValue = new TwinCollection(); twinValue["value"] = _bCelsius; twinValue["desiredVersion"] = desiredProperties["$version"]; twinValue["statusCode"] = 200; TwinCollection reportedProperties = new TwinCollection(); reportedProperties["isCelsius"] = twinValue; await _client.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false); } }
private async void SendDeviceProperties() { try { Debug.WriteLine("Sending device properties:"); Random random = new Random(); int newValue = random.Next(1, 6); // Show in UI ShowDieNumber(newValue); // Send to device twin TwinCollection telemetryConfig = new TwinCollection(); reportedProperties["dieNumber"] = newValue; Debug.WriteLine(JsonConvert.SerializeObject(reportedProperties)); await Client.UpdateReportedPropertiesAsync(reportedProperties); } catch (Exception ex) { Debug.WriteLine("Error in sample: {0}", ex.Message); } }
private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext) { try { desiredHumidity = desiredProperties["humidity"]; desiredTemperature = desiredProperties["temperature"]; greenMessage("Setting desired humidity to " + desiredProperties["humidity"]); greenMessage("Setting desired temperature to " + desiredProperties["temperature"]); // Report the properties back to the IoT Hub. var reportedProperties = new TwinCollection(); reportedProperties["fanstate"] = fanState.ToString(); reportedProperties["humidity"] = desiredHumidity; reportedProperties["temperature"] = desiredTemperature; await s_deviceClient.UpdateReportedPropertiesAsync(reportedProperties); greenMessage("\nTwin state reported: " + reportedProperties.ToJson()); } catch { redMessage("Failed to update device twin"); } }
private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext) { try { Console.WriteLine("Desired property change:"); Console.WriteLine(JsonConvert.SerializeObject(desiredProperties)); desiredPropertyValue = desiredProperties[desiredProperty]; Console.WriteLine($"Desired Property {desiredProperty} is now: {desiredPropertyValue}"); } catch (AggregateException ex) { foreach (Exception exception in ex.InnerExceptions) { Console.WriteLine(); Console.WriteLine("Error in sample: {0}", exception); } } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("Error in sample: {0}", ex.Message); } }
private async Task Twin_DeviceSetsReportedPropertyAndServiceReceivesIt(Client.TransportType transport) { var propName = Guid.NewGuid().ToString(); var propValue = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false); using (RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString)) using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport)) { var patch = new TwinCollection(); patch[propName] = propValue; await deviceClient.UpdateReportedPropertiesAsync(patch).ConfigureAwait(false); await deviceClient.CloseAsync().ConfigureAwait(false); var serviceTwin = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false); Assert.AreEqual <string>(serviceTwin.Properties.Reported[propName].ToString(), propValue); _log.WriteLine("verified " + serviceTwin.Properties.Reported[propName].ToString() + "=" + propValue); } }
private static async Task HandleSettingChanged(TwinCollection desiredProperties, object userContext) { try { Console.WriteLine("Received settings change..."); Console.WriteLine(JsonConvert.SerializeObject(desiredProperties)); string setting = "ANT"; if (desiredProperties.Contains(setting)) { // Act on setting change, then AcknowledgeSettingChange(desiredProperties, setting); } await Client.UpdateReportedPropertiesAsync(reportedProperties); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("Error in sample: {0}", ex.Message); } }
private async void iotHubButton_Click(object sender, RoutedEventArgs e) { try { using (var client = DeviceClient.CreateFromConnectionString( $"HostName=BOSCC-IOTHub.azure-devices.net;DeviceId=GraniteStHacker;SharedAccessKey={Credentials.LuisAccessKeyFromAzurePortal}", TransportType.Mqtt)) { var twinProperties = new TwinCollection(); twinProperties["MeasuredTemperature"] = manager.MeasuredTemperature; twinProperties["HeaterPowerOn"] = manager.HeaterPowerOn; twinProperties["ACPowerOn"] = manager.ACPowerOn; twinProperties["Device_BOSCC"] = DateTime.Now.ToString(); await client.UpdateReportedPropertiesAsync(twinProperties); Console.WriteLine("Done"); } } catch (Exception ex) { Console.WriteLine(ex); } }
void PopulateDesiredFirmwareFromDesiredProperties(TwinCollection desired, bool overwriteIfAbsent) { if (!desired.Contains(FirwarePropertyName) && overwriteIfAbsent) { this.desiredFirmware = this.currentFirmware.Clone(); return; } if (this.desiredFirmware == null) { this.desiredFirmware = (JObject.FromObject(desired[FirwarePropertyName])).ToObject <Firmware>(); return; } var firmwarePatch = JObject.FromObject(desired[FirwarePropertyName]); var desiredBefore = JObject.FromObject(this.desiredFirmware); desiredBefore.Merge(firmwarePatch, new JsonMergeSettings { MergeNullValueHandling = MergeNullValueHandling.Ignore }); this.desiredFirmware = desiredBefore.ToObject <Firmware>(); Console.WriteLine($"Desired Firmware version changed : {JsonConvert.SerializeObject(this.desiredFirmware, Formatting.Indented)}"); }
public static T GetPropertyValue <T>(this TwinCollection collection, string componentName, string propertyName) { T result = default(T); if (collection.Contains(componentName)) { var componentJson = collection[componentName] as JObject; CheckComponentFlag(componentJson, componentName); if (componentJson.ContainsKey(propertyName)) { var propertyJson = componentJson[propertyName] as JObject; if (propertyJson != null) { if (propertyJson.ContainsKey("value")) { var propertyValue = propertyJson["value"]; result = propertyValue.Value <T>(); } } } } return(result); }
// Callback for responding to desired property changes static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext) { ConsoleHelper.WriteGreenMessage("Desired property changed:"); ConsoleHelper.WriteGreenMessage($"{desiredProperties.ToJson()}"); // Execute firmware update if (desiredProperties.Contains("firmware") && (desiredProperties["firmware"] != null)) { // In the desired properties, we will find the following information: // fwVersion: the version number of the new firmware to flash // fwPackageURI: URI from where to download the new firmware binary // fwPackageCheckValue: Hash for validating the integrity of the // binary downloaded // We will assume the version of the firmware is a new one TwinCollection fwProperties = new TwinCollection(desiredProperties["firmware"].ToString()); await UpdateFirmware( (DeviceClient)userContext, fwProperties["fwVersion"].ToString(), fwProperties["fwPackageURI"].ToString(), fwProperties["fwPackageCheckValue"].ToString()); } }
public async Task UpdateReportedPropertiesAsync(TwinCollection patch) { Events.UpdatingReportedProperties(); try { if (!this.moduleClient.HasValue) { Events.UpdateReportedPropertiesDeviceClientEmpty(); } if (await this.WaitForDeviceClientInitialization()) { await this.moduleClient.ForEachAsync(d => d.UpdateReportedPropertiesAsync(patch)); Events.UpdatedReportedProperties(); } } catch (Exception e) { Events.ErrorUpdatingReportedProperties(e); throw; } }
async Task HandleDesiredPropertiesUpdate(Core.IMessage desiredPropertiesUpdate) { try { TwinCollection patch = this.twinCollectionMessageConverter.FromMessage(desiredPropertiesUpdate); using (await this.configLock.LockAsync()) { Option <EdgeHubConfig> edgeHubConfig = await this.lastDesiredProperties .Map(baseline => this.PatchDesiredProperties(baseline, patch)) .GetOrElse(() => this.GetConfigInternal()); edgeHubConfig.ForEach( config => { this.ConfigUpdated?.Invoke(this, config); }); } } catch (Exception ex) { Events.ErrorHandlingDesiredPropertiesUpdate(ex); } }
public static async void SendDeviceProperties() { try { Console.Write($"{DateTime.Now} > Sending device properties: "); TwinCollection reportedProperties = new TwinCollection(); reportedProperties["bluetoothAddress"] = "DESKTOP-531NK3L"; //text reportedProperties["beaconType"] = "00"; //text reportedProperties["rssi"] = "rrrr"; //text reportedProperties["uuid"] = "uuuuu"; //text Console.WriteLine(JsonConvert.SerializeObject(reportedProperties)); await Client.UpdateReportedPropertiesAsync(reportedProperties); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("Error in sample: {0}", ex.Message); } }
static async Task OnDesiredPropertiesUpdated(TwinCollection desiredPropertiesPatch, object userContext) { // At this point just update the configure configuration. if (desiredPropertiesPatch.Contains(SendIntervalConfigKey)) { messageDelay = TimeSpan.FromSeconds((int)desiredPropertiesPatch[SendIntervalConfigKey]); } if (desiredPropertiesPatch.Contains(SendDataConfigKey)) { bool desiredSendDataValue = (bool)desiredPropertiesPatch[SendDataConfigKey]; if (desiredSendDataValue != sendData && !desiredSendDataValue) { Console.WriteLine("Sending data disabled. Change twin configuration to start sending again."); } sendData = desiredSendDataValue; } var moduleClient = (ModuleClient)userContext; var patch = new TwinCollection($"{{ \"SendData\":{sendData.ToString().ToLower()}, \"SendInterval\": {messageDelay.TotalSeconds}}}"); await moduleClient.UpdateReportedPropertiesAsync(patch); // Just report back last desired property. }
private async Task PropertyHandler(TwinCollection desiredProperties, object userContext) { Logger.LogInformation("PropertyHandler called"); if (!(userContext is Dictionary <string, SubscriptionCallback> callbacks)) { throw new InvalidOperationException("UserContext doesn't contain a valid SubscriptionCallback"); } Logger.LogInformation("Desired property change:"); Logger.LogInformation(JsonConvert.SerializeObject(desiredProperties)); foreach (var callback in callbacks) { if (desiredProperties.Contains($"___{callback.Key}")) { var input = TypeTwin.CreateTwin(callback.Value.Type, callback.Key, desiredProperties); var invocationResult = callback.Value.Handler.DynamicInvoke(input); await(Task <TwinResult>) invocationResult; } } }