public async Task OnDesiredPropertyUpdate(TwinCollection desiredProperties, object userContext) { await SetReportedPropertyAsync(LastDesiredPropertyChangePropertyName, desiredProperties.ToJson()); Logger.LogInfo($"{DeviceID} received desired property update: {desiredProperties.ToJson()}"); foreach (var pair in desiredProperties.AsEnumerableFlatten()) { Func <object, Task> handler; if (_desiredPropertyUpdateHandlers.TryGetValue(pair.Key, out handler)) { try { await handler(pair.Value.Value.Value); Logger.LogInfo($"Successfully called desired property update handler {handler.Method.Name} on {DeviceID}"); } catch (Exception ex) { Logger.LogError($"Exception raised while processing desired property {pair.Key} change on device {DeviceID}: {ex.Message}"); } } else { Logger.LogWarning($"Cannot find desired property update handler for {pair.Key} on {DeviceID}"); } } }
/// <summary> /// Cross synchonize DeviceProperties and ReportedProperties /// </summary> /// <returns></returns> protected void CrossSyncProperties(TwinCollection patch, TwinCollection reported, bool regenerate) { var devicePropertiesType = DeviceProperties.GetType(); var reportedPairs = reported.AsEnumerableFlatten().ToDictionary(pair => pair.Key, pair => pair.Value); if (!regenerate) { // Overwrite regenerated DeviceProperties by current ReportedProperties foreach (var pair in reportedPairs) { string devicePropertyName = _propertyMapping.SingleOrDefault(p => p.Value == pair.Key).Key; if (string.IsNullOrWhiteSpace(devicePropertyName)) { continue; } try { DeviceProperties.SetProperty(devicePropertyName, pair.Value.Value); } catch { // Ignore any failure while overwriting the DeviceProperties } } } // Add missing DeviceProperties to ReportedProperties foreach (var property in devicePropertiesType.GetProperties()) { string reportedName; if (!_propertyMapping.TryGetValue(property.Name, out reportedName)) { continue; } var value = property.GetValue(DeviceProperties); if (regenerate || value != null && !reportedPairs.ContainsKey(reportedName)) { patch.Set(reportedName, value); } } }
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; }