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 static Task onDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext) { var moduleClient = userContext as ModuleClient; if (moduleClient == null) { throw new InvalidOperationException("UserContext doesn't contain " + "expected values"); } if (desiredProperties.Contains("IMAGE_POLLING_INTERVAL")) { //update the Polling Interval (if possible) var updated = TimeSpan.TryParse(desiredProperties["IMAGE_POLLING_INTERVAL"], out IMAGE_POLLING_INTERVAL); if (updated) { Console.WriteLine("IMAGE_POLLING_INTERVAL Updated."); moduleClient.UpdateReportedPropertiesAsync(desiredProperties); } } if (desiredProperties.Contains("MODE")) { //update the MODE var updated = Enum.TryParse <OperatingMode>(desiredProperties["MODE"], out MODE); if (updated) { Console.WriteLine("MODE Updated."); moduleClient.UpdateReportedPropertiesAsync(desiredProperties); } } return(Task.CompletedTask); }
private static async Task OnDesiredPropertyChange(TwinCollection desiredproperties, object usercontext) { if (desiredproperties.Contains("deviceTwinConfig")) { Message message; var deviceTwinConfig = JsonConvert.DeserializeObject <DesiredDeviceTwinConfiguration>( desiredproperties["deviceTwinConfig"].ToString()); // ignore delay for now. Just want to see if it can be parsed. int delay; if (int.TryParse(deviceTwinConfig.MessageSendDelay, out delay)) { lock (Locker) { _twinDesiredProperties = deviceTwinConfig; _propertyChangeStatus = Status.Pending; } message = new Message( Encoding.ASCII.GetBytes( $"Device accepted messageSendDelay value: `{deviceTwinConfig.MessageSendDelay}`. Property change is pending call to 'acceptDesiredProperties'.") ); message.Properties.Add(MessageProperty.Type.ToString("G"), Type.ConfigChage.ToString("G")); message.Properties.Add(MessageProperty.Status.ToString("G"), Status.Pending.ToString("G")); message.Properties.Add(MessageProperty.Severity.ToString("G"), Severity.Critical.ToString("G")); } else { _propertyChangeStatus = Status.Rejected; ($"Device Twin Property `messageSendDelay` is set to an illegal value: `{deviceTwinConfig.MessageSendDelay}`, " + $"change status is 'rejected'. Sending Critical Notification.").LogMessage(ConsoleColor.Red); message = new Message( Encoding.ASCII.GetBytes( $"Parameter messageSendDelay value: `{deviceTwinConfig.MessageSendDelay}`, could not be converted to an Int.")); message.Properties.Add(MessageProperty.Type.ToString("G"), Type.ConfigChage.ToString("G")); message.Properties.Add(MessageProperty.Status.ToString("G"), Status.Rejected.ToString("G")); message.Properties.Add(MessageProperty.Severity.ToString("G"), Severity.Critical.ToString("G")); } await _deviceClient.SendEventAsync(message); } }
static Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext) { if (desiredProperties.Contains("POLLINGfrequency")) { POLLINGfrequency = (int)desiredProperties["POLLINGfrequency"]; } if (desiredProperties.Contains("POLLINGHost")) { POLLINGHost = (string)desiredProperties["POLLINGHost"]; } // also reporting our Reported properties JObject twinResponse = new JObject(); twinResponse["POLLINGfrequency"] = POLLINGfrequency; twinResponse["POLLINGHost"] = POLLINGHost; Console.WriteLine("Sending TWIN: " + twinResponse.ToString()); TwinCollection patch = new TwinCollection(twinResponse.ToString()); ioTHubModuleClient.UpdateReportedPropertiesAsync(patch); return(Task.CompletedTask); }
protected override async Task OnDesiredModulePropertyChanged(TwinCollection newDesiredProperties) { Log.WriteLine("derived desired properties contains {0} properties", newDesiredProperties.Count); await base.OnDesiredModulePropertyChanged(newDesiredProperties); DesiredPropertiesType <ConfigurationType> dp; if (!newDesiredProperties.Contains(Keys.Configuration)) { Log.WriteLine("derived desired properties contains no configuration. skipping..."); return; } dp.Configuration = ((JObject)newDesiredProperties[Keys.Configuration]).ToObject <ConfigurationType>(); Log.WriteLine("checking for update current desiredProperties {0} new dp {1}", _desiredProperties.ToString(), dp.ToString()); var changed = _desiredProperties.Update(dp); if (changed) { Log.WriteLine("desired properties {0} different then current properties, notifying...", _desiredProperties.ToString()); ConfigurationChanged?.Invoke(this, dp.Configuration); Log.WriteLine("local notification complete. updating reported properties to cloud twin"); await UpdateReportedPropertiesAsync(new KeyValuePair <string, Object>(Keys.Configuration, JsonConvert.SerializeObject(_desiredProperties.Configuration))); } if (newDesiredProperties.Contains(Keys.FruitTest)) { var fruit = (string)((JValue)newDesiredProperties[Keys.FruitTest]).Value; Log.WriteLine("fruittest {0}", fruit != null ? fruit : "(null)"); if (fruit != null) { Log.WriteLine("setting fruit {0}", fruit); FruitChanged?.Invoke(this, fruit); } } Log.WriteLine("update complete -- current properties {0}", _desiredProperties.ToString()); }
async Task <Dictionary <string, string> > ValidatePropertiesFromTwinAsync(Twin receivedTwin) { TwinCollection propertyUpdatesFromTwin = receivedTwin.Properties.Desired; Dictionary <string, DateTime> desiredPropertiesUpdated = await this.storage.GetAllDesiredPropertiesUpdatedAsync(); Dictionary <string, DateTime> desiredPropertiesReceived = await this.storage.GetAllDesiredPropertiesReceivedAsync(); Dictionary <string, string> propertiesToRemoveFromTwin = new Dictionary <string, string>(); foreach (KeyValuePair <string, DateTime> desiredPropertyUpdate in desiredPropertiesUpdated) { bool hasTwinUpdate = propertyUpdatesFromTwin.Contains(desiredPropertyUpdate.Key); bool hasModuleReceivedCallback = desiredPropertiesReceived.ContainsKey(desiredPropertyUpdate.Key); string status; if (hasTwinUpdate && hasModuleReceivedCallback) { status = $"{(int)StatusCode.ValidationSuccess}: Successfully validated desired property update"; Logger.LogInformation(status + $" {desiredPropertyUpdate.Key}"); } else if (this.ExceedFailureThreshold(this.twinState, desiredPropertyUpdate.Value)) { if (hasTwinUpdate && !hasModuleReceivedCallback) { status = $"{(int)StatusCode.DesiredPropertyUpdateNoCallbackReceived}: Failure receiving desired property update in callback"; } else if (!hasTwinUpdate && hasModuleReceivedCallback) { status = $"{(int)StatusCode.DesiredPropertyUpdateNotInEdgeTwin}: Failure receiving desired property update in twin"; } else { status = $"{(int)StatusCode.DesiredPropertyUpdateTotalFailure}: Failure receiving desired property update in both twin and callback"; } Logger.LogError($"{status} for update #{desiredPropertyUpdate.Key}"); } else { continue; } await this.HandleReportStatusAsync(Settings.Current.ModuleId, status); propertiesToRemoveFromTwin.Add(desiredPropertyUpdate.Key, null); // will later be serialized as a twin update } return(propertiesToRemoveFromTwin); }
// The OnDesiredPropertyChanged event handler accepts a desiredProperties // parameter of type TwinCollection. private static async Task OnDesiredPropertyChanged( TwinCollection desiredProperties, object userContext) { Console.WriteLine("Desired Twin Property Changed:"); Console.WriteLine($"{desiredProperties.ToJson()}"); // Read the desired Twin Properties if (desiredProperties.Contains("telemetryDelay")) { // Notice that if the value of the desiredProperties parameter // contains telemetryDelay (a device twin desired property), the // code will assign the value of the device twin property to the // telemetryDelay variable. You may recall that the // SendDeviceToCloudMessagesAsync method includes a Task.Delay // call that uses the telemetryDelay variable to set the delay // time between messages sent to IoT hub. string desiredTelemetryDelay = desiredProperties["telemetryDelay"]; if (desiredTelemetryDelay != null) { telemetryDelay = int.Parse(desiredTelemetryDelay); } // if desired telemetryDelay is null or unspecified, don't change it } // The next block of code is used to report the current state of the // device back up to Azure IoT Hub. This code calls the DeviceClient. // UpdateReportedPropertiesAsync method and passes it a // TwinCollection that contains the current state of the device // properties. // This is how the device reports back to IoT Hub that it received // the device twin desired properties changed event, and has now // updated its configuration accordingly. // Note that it reports what the properties are now set to, not an // echo of the desired properties. In the case where the reported // properties sent from the device are different than the desired // state that the device received, IoT Hub will maintain an accurate // Device Twin that reflects the state of the device. var reportedProperties = new TwinCollection(); reportedProperties["telemetryDelay"] = telemetryDelay.ToString(); await deviceClient .UpdateReportedPropertiesAsync(reportedProperties) .ConfigureAwait(false); Console.WriteLine("Reported Twin Properties:"); Console.WriteLine($"{reportedProperties.ToJson()}"); }
async Task <TwinCollection> ValidatePropertiesFromTwinAsync(Twin receivedTwin) { TwinCollection propertyUpdatesFromTwin = receivedTwin.Properties.Reported; Dictionary <string, DateTime> reportedPropertiesUpdated = await this.storage.GetAllReportedPropertiesUpdatedAsync(); TwinCollection propertiesToRemove = new TwinCollection(); foreach (KeyValuePair <string, DateTime> reportedPropertyUpdate in reportedPropertiesUpdated) { string status; if (propertyUpdatesFromTwin.Contains(reportedPropertyUpdate.Key)) { if (this.reportedPropertyKeysFailedToReceiveWithinThreshold.Contains(reportedPropertyUpdate.Key)) { this.reportedPropertyKeysFailedToReceiveWithinThreshold.Remove(reportedPropertyUpdate.Key); status = $"{(int)StatusCode.ReportedPropertyReceivedAfterThreshold}: Successfully validated reported property update (exceeded failure threshold)"; } else { status = $"{(int)StatusCode.ValidationSuccess}: Successfully validated reported property update"; } await this.HandleReportStatusAsync(status); Logger.LogInformation($"{status} for reported property update {reportedPropertyUpdate.Key}"); propertiesToRemove[reportedPropertyUpdate.Key] = null; // will later be serialized as a twin update } else if (!this.reportedPropertyKeysFailedToReceiveWithinThreshold.Contains(reportedPropertyUpdate.Key) && this.DoesExceedFailureThreshold(this.twinTestState, reportedPropertyUpdate.Key, reportedPropertyUpdate.Value)) { this.reportedPropertyKeysFailedToReceiveWithinThreshold.Add(reportedPropertyUpdate.Key); status = $"{(int)StatusCode.ReportedPropertyUpdateNotInCloudTwin}: Failure receiving reported property update"; await this.HandleReportStatusAsync(status); Logger.LogInformation($"{status} for reported property update {reportedPropertyUpdate.Key}"); } else if (this.DoesExceedCleanupThreshold(this.twinTestState, reportedPropertyUpdate.Key, reportedPropertyUpdate.Value)) { status = $"{(int)StatusCode.ReportedPropertyUpdateNotInCloudTwinAfterCleanUpThreshold}: Failure receiving reported property update after cleanup threshold"; await this.HandleReportStatusAsync(status); Logger.LogInformation($"{status} for reported property update {reportedPropertyUpdate.Key}"); propertiesToRemove[reportedPropertyUpdate.Key] = null; // will later be serialized as a twin update } } return(propertiesToRemove); }
public static JObject GetOrCreateComponent(this TwinCollection collection, string componentName) { if (collection.Contains(componentName)) { var component = collection[componentName] as JObject; CheckComponentFlag(component, componentName); } else { JToken flag = JToken.Parse("{\"__t\" : \"c\"}"); collection[componentName] = flag; } JObject componentJson = collection[componentName] as JObject; return(componentJson); }
private static async Task UpdateDeviceProperties(TwinCollection desiredProperties) { // Set properties based on Desired Properties (from Device Twin stored in cloud) if (desiredProperties.Contains("sensorDataReportIntervalMinutes")) { sensorDataReportIntervalMinutes = desiredProperties["sensorDataReportIntervalMinutes"]; } // Set Reported Propeeties based on actual device settings TwinCollection reportedProperties = new TwinCollection(); reportedProperties["sensorDataReportIntervalMinutes"] = sensorDataReportIntervalMinutes; // Update Device Twin stored in the cloud await deviceClient.UpdateReportedPropertiesAsync(reportedProperties); }
static double?TryGetDesiredPropertyDouble(TwinCollection desiredProperties, string propertyName) { if (desiredProperties.Contains(propertyName)) { var raw = desiredProperties[propertyName]?.ToString() ?? string.Empty; if (!string.IsNullOrEmpty(raw)) { if (double.TryParse(raw, out double value)) { return(value); } } } return(null); }
private async Task HandleDeviceEnablement(TwinCollection desiredProperties, object userContext) { if (desiredProperties.Contains("status")) { DeviceStatus desiredStatus = (DeviceStatus)Enum.Parse(typeof(DeviceStatus), desiredProperties["status"].ToString()); if (desiredStatus == DeviceStatus.enabled) { // reset stock count this.TicketStockCount = deviceConfig.InitialStockCount; Console.WriteLine("Resetting Stock levels."); } } // hides compiler warning for async with no await await Task.Run(() => { }); }
private bool LightBulbFromTwins(TwinCollection twins) { if (twins == null || !twins.Contains(LightProperty)) { return(false); } var light = twins[LightProperty]; if (Enum.TryParse(light.Value, out TrafficLightState lightEnum)) { LightBulb(lightEnum); return(true); } return(false); }
/// <summary> /// Update Start from module Twin. /// </summary> static async Task DoTwinUpdate(TwinCollection desiredProperties, ModuleClient ioTHubModuleClient) { string serializedStr = JsonConvert.SerializeObject(desiredProperties); Console.WriteLine("Updating desired properties:"); Console.WriteLine(serializedStr); if (string.IsNullOrEmpty(serializedStr)) { Console.WriteLine("No configuration provided for the module Twin."); } else if (!desiredProperties.Contains(DriveProfileConfig.DriveProfileConfigSection)) { Console.WriteLine("No driverProfile configuration defined in Twin desired properties or local settings"); Console.WriteLine("Configuration must contain required section " + DriveProfileConfig.DriveProfileConfigSection); } else { Console.WriteLine("Attempt to parse configuration"); DriveProfileConfig config = JsonConvert.DeserializeObject <DriveProfileConfig>(serializedStr); ModuleMessageHandler moduleHandle = ModuleMessageHandler.CreateFromConfig(config); if (moduleHandle != null) { var userContext = new Tuple <ModuleClient, ModuleMessageHandler>(ioTHubModuleClient, moduleHandle); // Register callback to be called when a message is received by the module await ioTHubModuleClient.SetInputMessageHandlerAsync( "driveProfileInput", PipeMessage, userContext); Console.WriteLine("DriverProfile module was loaded sucessfully and listining for modbus messages."); } else { Console.WriteLine("Error creating modbus message handler. Message processing stopped."); } // Report current module config via moduleTwin serializedStr = JsonConvert.SerializeObject(config); TwinCollection reported = JsonConvert.DeserializeObject <TwinCollection>(serializedStr); await ioTHubModuleClient.UpdateReportedPropertiesAsync(reported); } }
// Callback for responding to desired property changes static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext) { LogToConsole("Desired property changed:"); LogToConsole($"{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()); } }
// check for module twin updates. Below is a sample value check private async Task UpdateDesiredProperties(TwinCollection desiredproperties, object usercontext, ModuleConfig moduleConfig) { if (desiredproperties.Contains(OpcUASampleValueKey)) { string value = desiredproperties[OpcUASampleValueKey].ToString(); if (!string.IsNullOrEmpty(value)) { moduleConfig.OpcUASampleValue = value; } Console.WriteLine($"{nameof(ModuleConfig.OpcUASampleValue)}: { moduleConfig.OpcUASampleValue}"); } if (usercontext is DeviceClient deviceClient) { await deviceClient.UpdateReportedPropertiesAsync(CreateTwinCollectionFromModuleConfig(moduleConfig)); } }
public void AddComponentPropAddsTheFlagIfNeeded() { TwinCollection collection = new TwinCollection(); collection.AddComponentProperty("myComp", "myProp", 12.3); Assert.True(collection.Contains("myComp")); var comp = collection["myComp"] as JObject; Assert.True(comp.ContainsKey("__t")); Assert.True(comp.ContainsKey("myProp")); var prop = comp["myProp"]; Assert.NotNull(prop); var propValue = prop["value"]; Assert.Equal(12.3, propValue.Value <double>()); }
T GetPropertyValue <T>(TwinCollection collection, string propertyName) { T result = default(T); if (collection.Contains(propertyName)) { var propertyJson = collection[propertyName] as JObject; if (propertyJson != null) { result = propertyJson.ToObject <T>(); } else { this.logger.LogError($"Property {propertyName} not found"); } } return(result); }
/// <summary> /// Process a collection of desired device twin properties /// Sends back the reported properties /// </summary> /// <param name="desiredProperties"></param> /// <returns></returns> private static async Task ProcessDesiredPropertiesUpdate(TwinCollection desiredProperties, ModuleClient moduleClient) { if (desiredProperties.Contains("samplingrate") && desiredProperties["samplingrate"].Type == JTokenType.Integer) { int desiredSamplingRate = desiredProperties["samplingrate"]; // only allow values between 1ms and 60000ms (1min) if (desiredSamplingRate >= 1 && desiredSamplingRate <= 60000) { Log.Information($"Setting samplingRate to {desiredSamplingRate}ms"); _samplingRateMs = desiredSamplingRate; } } _reportedProperties["samplingrate"] = _samplingRateMs; // Report properties back to IoT hub await moduleClient.UpdateReportedPropertiesAsync(_reportedProperties); }
private void UpdateOccupantStateReportedProperties(TwinCollection desiredProperties, TwinCollection reportedProperties) { const string occupantState = nameof(Config.Occupant); try { if (desiredProperties.Contains(occupantState)) { OccupantState newOccupantState = JsonConvert.DeserializeObject<OccupantState>(desiredProperties[occupantState].ToString()); _alarmState.OccupantStateChanged(Config.Occupant, newOccupantState); Config.Occupant = newOccupantState; reportedProperties[occupantState] = Config.Occupant; } } catch (Exception ex) { Log.Error($"Error on UpdateState '{occupantState}'", ex); } }
async Task <TwinCollection> ValidatePropertiesFromTwinAsync(Twin receivedTwin) { TwinCollection propertyUpdatesFromTwin = receivedTwin.Properties.Reported; Dictionary <string, DateTime> reportedPropertiesUpdated = await this.storage.GetAllReportedPropertiesUpdatedAsync(); TwinCollection propertiesToRemoveFromTwin = new TwinCollection(); foreach (KeyValuePair <string, DateTime> reportedPropertyUpdate in reportedPropertiesUpdated) { string status; if (propertyUpdatesFromTwin.Contains(reportedPropertyUpdate.Key)) { try { await this.storage.RemoveReportedPropertyUpdateAsync(reportedPropertyUpdate.Key); } catch (Exception e) { Logger.LogError(e, $"Failed to remove validated reported property id {reportedPropertyUpdate.Key} from storage."); continue; } status = $"{(int)StatusCode.ValidationSuccess}: Successfully validated reported property update"; Logger.LogInformation(status + $" {reportedPropertyUpdate.Key}"); } else if (this.ExceedFailureThreshold(this.twinState, reportedPropertyUpdate.Value)) { status = $"{(int)StatusCode.ReportedPropertyUpdateNotInCloudTwin}: Failure receiving reported property update"; Logger.LogInformation($"{status} for reported property update {reportedPropertyUpdate.Key}"); } else { continue; } propertiesToRemoveFromTwin[reportedPropertyUpdate.Key] = null; // will later be serialized as a twin update await this.HandleReportStatusAsync(status); } return(propertiesToRemoveFromTwin); }
private bool checkIsAValidSFDesiredProperty(TwinCollection desiredProperties) { try { if (desiredProperties.Contains(SfTwinProperties.SF_LASTUPDATED_TIMESTAMP)) { int lastUpdatedTS = desiredProperties[SfTwinProperties.SF_LASTUPDATED_TIMESTAMP]; Logger.showDebug(TAG, "lastUpdatedTS: {0}".FormatInvariant(lastUpdatedTS)); if (lastUpdatedTS != 0) { return(true); } } } catch (Exception ex) { Logger.showError(TAG, "checkIsAValidSFDesiredProperty Exception: {0}".FormatInvariant(ex.Message.ToString())); } return(false); }
static private void Set(this TwinCollection collection, IEnumerable <string> names, dynamic value) { var name = names.First(); if (names.Count() == 1) { // Current node is the target node, set the value collection[name] = value; } else if (!collection.Contains(name)) { // Current node is container, go to next level // The target collection is not exist, create and add it // Reminder: the 'add' operation perform 'copy' rather than 'link' var newCollection = new TwinCollection(); Set(newCollection, names.Skip(1), value); collection[name] = newCollection; } else { var child = collection[name]; if (child is TwinCollection) { // The target collection is there. Go to next level Set(child as TwinCollection, names.Skip(1), value); } else if (child is JContainer) { // The target collection is there. Go to next level Set(child as JContainer, names.Skip(1), value); } else { // Currently, the container could only be TwinCollection or JContainer #if DEBUG throw new ApplicationException(FormattableString.Invariant($"Unexpected TwinCollection item type: {child.GetType().FullName} @ ...{name}")); #endif } } }
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 async Task DesiredPropUpdated(TwinCollection desiredProperties, object userContext) { if (DesiredPropertiesUpdated != null) { DesiredPropertiesUpdated(deviceClient, new DesiredPropertiesUpdatedEventArgs() { DesiredProperties = desiredProperties }); } if (desiredProperties.Contains(updateIntervalCommand)) { lock (this) { TelemetryCycleMSec = desiredProperties[updateIntervalCommand]; } } var reportedProperties = new TwinCollection(); reportedProperties["DateTimeLastDisredPropertyChangeReceived"] = DateTime.Now; await deviceClient.UpdateReportedPropertiesAsync(reportedProperties); }
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.")) .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; }
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; } } }
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); } }
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); }
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); } }