// The desired property update callback, which receives the target temperature as a desired property update, // and updates the current temperature value over telemetry and reported property update. private static async Task TargetTemperatureUpdateCallbackAsync(TwinCollection desiredProperties, object userContext) { string propertyName = "targetTemperature"; (bool targetTempUpdateReceived, double targetTemperature) = GetPropertyFromTwin <double>(desiredProperties, propertyName); if (targetTempUpdateReceived) { s_logger.LogDebug($"Property: Received - {{ \"{propertyName}\": {targetTemperature}°C }}."); string jsonPropertyPending = $"{{ \"{propertyName}\": {{ \"value\": {s_temperature}, \"ac\": {(int)StatusCode.InProgress}, \"av\": {desiredProperties.Version} }} }}"; var reportedPropertyPending = new TwinCollection(jsonPropertyPending); await s_deviceClient.UpdateReportedPropertiesAsync(reportedPropertyPending); s_logger.LogDebug($"Property: Update - {{\"{propertyName}\": {targetTemperature}°C }} is {StatusCode.InProgress}."); // Update Temperature in 2 steps double step = (targetTemperature - s_temperature) / 2d; for (int i = 1; i <= 2; i++) { s_temperature = Math.Round(s_temperature + step, 1); await Task.Delay(6 * 1000); } string jsonProperty = $"{{ \"{propertyName}\": {{ \"value\": {s_temperature}, \"ac\": {(int)StatusCode.Completed}, \"av\": {desiredProperties.Version}, \"ad\": \"Successfully updated target temperature\" }} }}"; var reportedProperty = new TwinCollection(jsonProperty); await s_deviceClient.UpdateReportedPropertiesAsync(reportedProperty); s_logger.LogDebug($"Property: Update - {{\"{propertyName}\": {s_temperature}°C }} is {StatusCode.Completed}."); } else { s_logger.LogDebug($"Property: Received an unrecognized property update from service."); } }
private async Task RebootOrchestration() { string logPrefix = "c2ddirectmethods".BuildLogPrefix(); try { _logger.LogDebug($"{logPrefix}::{ModuleSettings.ArtifactId}::Reboot order received."); _logger.LogDebug($"{logPrefix}::{ModuleSettings.ArtifactId}::Stoping processes..."); _stopProcessing = true; _logger.LogDebug($"{logPrefix}::{ModuleSettings.ArtifactId}::Processes stopped."); _logger.LogDebug($"{logPrefix}::{ModuleSettings.ArtifactId}::Rebooting..."); // Update device twin with reboot time. TwinCollection reportedProperties, reboot, lastReboot, rebootStatus; lastReboot = new TwinCollection(); reboot = new TwinCollection(); reportedProperties = new TwinCollection(); rebootStatus = new TwinCollection(); lastReboot["lastReboot"] = DateTime.Now; reboot["reboot"] = lastReboot; reboot["rebootStatus"] = "rebooting"; reportedProperties["iothubDM"] = reboot; await _moduleClient.UpdateReportedPropertiesAsync(reportedProperties); await Task.Delay(10000); // Update device twin with reboot time. reboot["rebootStatus"] = "online"; reportedProperties["iothubDM"] = reboot; await _moduleClient.UpdateReportedPropertiesAsync(reportedProperties); _logger.LogDebug($"{logPrefix}::{ModuleSettings.ArtifactId}::Reboot over and system runing again."); } catch (Exception ex) { _logger.LogError($"{logPrefix}::{ModuleSettings.ArtifactId}::ERROR::RebootOrchestration:{ex.Message}."); } finally { _stopProcessing = false; } }
static async void GenTwinUpdate(ModuleClient client) { var twin = new TwinCollection(); twin["messagesSent"] = MessageIdCounter; await client.UpdateReportedPropertiesAsync(twin).ConfigureAwait(false); }
internal virtual async Task <T> PublishTwinAsync <T>(string name, T twin) where T : TypeTwin, new() { await _ioTHubModuleClient.UpdateReportedPropertiesAsync(twin.GetReportedProperties()); return(twin); }
static Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext) { Console.WriteLine("Received TWIN: " + desiredProperties.ToString()); if (desiredProperties.Contains("RESTTargetURL")) { RESTTargetURL = (string)desiredProperties["RESTTargetURL"]; } if (desiredProperties.Contains("RESTTargetLocation")) { RESTTargetLocation = (string)desiredProperties["RESTTargetLocation"]; } if (desiredProperties.Contains("POLLINGInterval")) { POLLINGInterval = (int)desiredProperties["POLLINGInterval"]; } // also reporting our Reported properties JObject twinResponse = new JObject(); twinResponse["RESTTargetURL"] = RESTTargetURL; twinResponse["RESTTargetLocation"] = RESTTargetLocation; twinResponse["POLLINGInterval"] = POLLINGInterval; Console.WriteLine("Sending TWIN: " + twinResponse.ToString()); TwinCollection patch = new TwinCollection(twinResponse.ToString()); ioTHubModuleClient.UpdateReportedPropertiesAsync(patch); return(Task.CompletedTask); }
private async static Task UpdateReportedProperties(ModuleClient ioTHubModuleClient, OperationStatus status) { var reportedProperties = new TwinCollection(); reportedProperties[Constants.RabbitMQConfigPropertyName] = status.ToString(); await ioTHubModuleClient.UpdateReportedPropertiesAsync(reportedProperties); }
/// <summary> /// Initializes the ModuleClient and sets up the callback to receive /// messages containing temperature information /// </summary> static async Task Init() { MqttTransportSettings mqttSetting = new MqttTransportSettings(TransportType.Mqtt_Tcp_Only); ITransportSettings[] settings = { mqttSetting }; // Open a connection to the Edge runtime ModuleClient ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings); await ioTHubModuleClient.OpenAsync(); Console.WriteLine("IoT Hub module client initialized."); // reset reported properties var reportedProperties = new Microsoft.Azure.Devices.Shared.TwinCollection(); reportedProperties["highTemperature"] = (float)0; reportedProperties["highTemperatureDate"] = string.Empty; await ioTHubModuleClient.UpdateReportedPropertiesAsync(reportedProperties); Console.WriteLine("Reset Reported Properties"); // Register callback to be called when a message is received by the module await ioTHubModuleClient.SetInputMessageHandlerAsync("reporter", PipeMessage, ioTHubModuleClient); }
/// <summary> /// Creating new task per port with updated desired properties /// </summary> private static async Task SetupNewTasks(TwinCollection desiredProperties, ModuleClient client) { Log.Debug("Changing desired properties"); try { var serializedStr = JsonConvert.SerializeObject(desiredProperties); Log.Verbose($"Incoming desired properties change: '{serializedStr}'"); ModuleConfig moduleConfig = JsonConvert.DeserializeObject <ModuleConfig>(serializedStr); moduleConfig.Validate(); //// After setting all desired properties, we initialize and start 'read' and 'write' ports again Log.Debug("New desired twins are loaded into memory"); foreach (var dict in moduleConfig.PortConfigs) { var port = dict.Key; var portConfig = dict.Value; Log.Debug($"Adding task '{port}'"); var t = Task.Run(async() => { await SerialTaskBody(port, portConfig, client, _serialMessageBroadcaster); }); _taskList.Add(t); Log.Debug($"Task '{port}' added ({_taskList.Count} tasks loaded)"); } // report back received properties string reportedPropertiesJson = JsonConvert.SerializeObject(moduleConfig); Log.Verbose($"Reported properties: '{reportedPropertiesJson}'"); var reportedProperties = new TwinCollection(reportedPropertiesJson); await client.UpdateReportedPropertiesAsync(reportedProperties); Log.Debug("Desired properties set"); } catch (AggregateException ex) { Log.Error($"Error when receiving desired property: '{ex.Message}'"); foreach (Exception exception in ex.InnerExceptions) { Log.Debug($"Inner exception when receiving desired property: '{exception}'"); } } catch (Exception ex) { Log.Error($"Exception when receiving desired property: '{ex.Message}'"); } }
private static void reportLatency(string taskName, TimeSpan endToEndDuration, ModuleClient moduleClient) { TwinCollection reportedProperties = new TwinCollection(); reportedProperties[$"LATENCY_{taskName}"] = endToEndDuration.TotalMilliseconds; moduleClient.UpdateReportedPropertiesAsync(reportedProperties); }
public async Task UpdateReportedProperties(string luss) { TwinCollection collection = new TwinCollection(); collection["luss"] = luss; collection["timestamp"] = DateTime.UtcNow.ToString(); await client.UpdateReportedPropertiesAsync(collection); }
static async Task SetAlertStatus(string status) { Console.WriteLine($"Sending alert as reported property with value `{status}`."); TwinCollection reportedProperties = new TwinCollection { ["alert"] = status }; await _ioTHubModuleClient.UpdateReportedPropertiesAsync(reportedProperties); }
static Task <MethodResponse> CheckMethod(MethodRequest methodRequest, object userContext) { Console.WriteLine("Received Check direct method call..."); try { var directMethod = new TwinCollection(); directMethod["CheckTime"] = DateTime.Now; reportedProperties["DirectMethod"] = directMethod; moduleClient.UpdateReportedPropertiesAsync(reportedProperties).Wait(); } catch (Exception ex) { Console.WriteLine(ex.Message); } var response = new MethodResponse((int)System.Net.HttpStatusCode.OK); return(Task.FromResult(response)); }
public static Task ResetTwinReportedPropertiesAsync(ModuleClient moduleClient, Twin originalTwin) { TwinCollection cleanedReportedProperties = new TwinCollection(); foreach (dynamic twinUpdate in originalTwin.Properties.Reported) { KeyValuePair <string, object> pair = (KeyValuePair <string, object>)twinUpdate; cleanedReportedProperties[pair.Key] = null; // erase twin property by assigning null } return(moduleClient.UpdateReportedPropertiesAsync(cleanedReportedProperties)); }
public async Task RunSampleAsync() { await _moduleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null).ConfigureAwait(false); Console.WriteLine("Retrieving twin..."); Twin twin = await _moduleClient.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 _moduleClient.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); }
private async Task TWINUpdate() { twinJSON = new JObject(); twinJSON["isActive"] = isActive; twinJSON["bootTimeEPOCH"] = bootTimeEPOCH; twinJSON["lastElection"] = lastElection; twinJSON["peers"] = peersString; twinJSON["udpPort"] = UDPPort; twinJSON["broadcastSubnet"] = monitoredSubnetNetwork; twinJSON["probeIntervalMS"] = l_probeIntervalMS; twinJSON["failedProbeCount"] = failedProbes; stateTwin = new TwinCollection("{\"IoTEdgeModuleHA\": " + twinJSON.ToString() + "}"); await moduleClient.UpdateReportedPropertiesAsync(stateTwin); }
static async void GenTwinUpdate(ModuleClient client, Guid batchId) { var twin = new TwinCollection(); long sequenceNumber = messageIdCounter; twin["messagesSent"] = sequenceNumber; try { await client.UpdateReportedPropertiesAsync(twin).ConfigureAwait(false); } catch (Exception e) { Log.Error($"Sequence number {sequenceNumber}, BatchId: {batchId.ToString()} {e}"); } }
public static async Task <TwinAllOperationsInitializer> CreateAsync(RegistryManager registryManager, ModuleClient moduleClient, ITwinTestResultHandler resultHandler, TwinEventStorage storage) { try { TwinState initializedState; Twin twin = await registryManager.GetTwinAsync(Settings.Current.DeviceId, Settings.Current.ModuleId); Dictionary <string, DateTime> reportedPropertyUpdates = await storage.GetAllReportedPropertiesUpdatedAsync(); Dictionary <string, DateTime> desiredPropertyUpdates = await storage.GetAllDesiredPropertiesUpdatedAsync(); if (reportedPropertyUpdates.Count == 0 && desiredPropertyUpdates.Count == 0 && (await storage.GetAllDesiredPropertiesReceivedAsync()).Count == 0) { Logger.LogInformation("No existing storage detected. Initializing new module twin for fresh run."); // reset desired properties Twin desiredPropertyResetTwin = await registryManager.ReplaceTwinAsync(Settings.Current.DeviceId, Settings.Current.ModuleId, new Twin(), twin.ETag); // reset reported properties TwinCollection eraseReportedProperties = GetReportedPropertiesResetTwin(desiredPropertyResetTwin); await moduleClient.UpdateReportedPropertiesAsync(eraseReportedProperties); await Task.Delay(TimeSpan.FromSeconds(10)); // give enough time for reported properties reset to reach cloud twin = await registryManager.GetTwinAsync(Settings.Current.DeviceId, Settings.Current.ModuleId); initializedState = new TwinState { ReportedPropertyUpdateCounter = 0, DesiredPropertyUpdateCounter = 0, TwinETag = twin.ETag, LastTimeOffline = DateTime.MinValue }; } else { Logger.LogInformation("Existing storage detected. Initializing reported / desired property update counters."); initializedState = new TwinState { ReportedPropertyUpdateCounter = GetNewPropertyCounter(reportedPropertyUpdates), DesiredPropertyUpdateCounter = GetNewPropertyCounter(desiredPropertyUpdates), TwinETag = twin.ETag, LastTimeOffline = DateTime.MinValue }; } Logger.LogInformation($"Start state of module twin: {JsonConvert.SerializeObject(twin, Formatting.Indented)}"); return(new TwinAllOperationsInitializer(registryManager, moduleClient, resultHandler, storage, initializedState)); } catch (Exception e) { throw new Exception($"Shutting down module. Initialization failure: {e}"); } }
static async Task GenerateTwinUpdateAsync(ModuleClient client, Guid batchId) { var twin = new TwinCollection(); long sequenceNumber = messageIdCounter; twin["messagesSent"] = sequenceNumber; try { await client.UpdateReportedPropertiesAsync(twin); } catch (Exception e) { Logger.LogError($"[GenerateTwinUpdateAsync] Sequence number {sequenceNumber}, BatchId: {batchId.ToString()};{Environment.NewLine}{e}"); } }
/// <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); } }
private async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext) { var cancellationToken = (CancellationToken)userContext; _logger.LogInformation($"Desired property changed: {desiredProperties.ToJson()}"); TwinCollection reportedProperties = new TwinCollection(); reportedProperties["DateTimeLastDesiredPropertyChangeReceived"] = DateTimeOffset.Now.ToUniversalTime(); // If cancellation has not been requested, and the device is connected, then send the reported property update. while (!cancellationToken.IsCancellationRequested) { if (s_connectionStatus == ConnectionStatus.Connected) { try { await s_moduleClient.UpdateReportedPropertiesAsync(reportedProperties, cancellationToken); _logger.LogInformation($"Sent current time as reported property update: {reportedProperties.ToJson()}"); break; } catch (IotHubException ex) when(ex.IsTransient) { // Inspect the exception to figure out if operation should be retried, or if user-input is required. _logger.LogError($"An IotHubException was caught, but will try to recover and retry: {ex}"); } catch (Exception ex) when(ExceptionHelper.IsNetworkExceptionChain(ex)) { _logger.LogError($"A network related exception was caught, but will try to recover and retry: {ex}"); } catch (Exception ex) { _logger.LogError($"Unexpected error {ex}"); } // wait and retry await Task.Delay(s_sleepDuration); } // wait and retry await Task.Delay(s_sleepDuration); } }
/// <summary> /// Handle updates on the desired properties. /// </summary> static async Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext) { try { Log($"Desired property change:\n{desiredProperties.ToJson(Formatting.Indented)}"); if (desiredProperties["SensorId"] != null) { _customersSimulation.SensorId = desiredProperties["SensorId"]; } if (desiredProperties["MaxCapacity"] != null) { _customersSimulation.MaxCapacity = desiredProperties["MaxCapacity"]; } if (desiredProperties["StoreStatus"] != null) { _customersSimulation.StoreStatus = (StoreStatus)desiredProperties["StoreStatus"]; } // report back desired properties var reported = new { SensorId = _customersSimulation.SensorId, MaxCapacity = _customersSimulation.MaxCapacity, StoreStatus = _customersSimulation.StoreStatus.ToString() }; var json = JsonConvert.SerializeObject(reported); var patch = new TwinCollection(json); await _moduleClient.UpdateReportedPropertiesAsync(patch); // Just report back last desired property. } catch (AggregateException ex) { foreach (Exception exception in ex.InnerExceptions) { Log($"Error when receiving desired property: {exception.ToString()}"); } } catch (Exception ex) { Log($"Error when receiving desired property: {ex.Message}"); } }
/// <summary> /// Updates the desired properties on change during runtime. /// </summary> private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext) { try { ReadDesiredProperties(desiredProperties); ModuleClient ioTHubModuleClient = (ModuleClient)userContext; TwinCollection reportedProperties = new TwinCollection(); reportedProperties["DateTimeLastDesiredPropertyChangeReceived"] = DateTime.Now; await ioTHubModuleClient.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false); } catch (Exception ex) { Console.WriteLine("Exception in OnDesiredPropertyChanged"); Console.WriteLine(ex); } }
/// <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); }
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; } ModuleClient moduleClient = (ModuleClient)userContext; TwinCollection patch = new TwinCollection($"{{ \"SendData\":{sendData.ToString().ToLower()}, \"SendInterval\": {messageDelay.TotalSeconds}}}"); await moduleClient.UpdateReportedPropertiesAsync(patch); // Just report back last desired property. }
// Handle property updates static async Task onDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext) { try { Console.WriteLine("Desired property change:"); Console.WriteLine(JsonConvert.SerializeObject(desiredProperties)); if (desiredProperties.Count > 0) { if (desiredProperties["interval"] != null) { interval = desiredProperties["interval"]; } } var propertiesToUpdate = new { interval = interval }; var reportedProperties = new TwinCollection(JsonConvert.SerializeObject(propertiesToUpdate)); await ioTHubModuleClient.UpdateReportedPropertiesAsync(reportedProperties); } 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); } }
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); }
/// <summary> /// Update Start from module Twin. /// </summary> static async Task UpdateStartFromTwin(TwinCollection desiredProperties, ModuleClient ioTHubModuleClient) { ModuleConfig config; Slaves.ModuleHandle moduleHandle; string jsonStr = null; string serializedStr; serializedStr = JsonConvert.SerializeObject(desiredProperties); Console.WriteLine("Desired property change:"); Console.WriteLine(serializedStr); if (desiredProperties.Contains(ModbusSlaves)) { // get config from Twin jsonStr = serializedStr; } else { Console.WriteLine("No configuration found in desired properties, look in local..."); if (File.Exists(@"iot-edge-modbus.json")) { try { // get config from local file jsonStr = File.ReadAllText(@"iot-edge-modbus.json"); } catch (Exception ex) { Console.WriteLine("Load configuration error: " + ex.Message); } } else { Console.WriteLine("No configuration found in local file."); } } if (!string.IsNullOrEmpty(jsonStr)) { Console.WriteLine("Attempt to load configuration: " + jsonStr); config = JsonConvert.DeserializeObject <ModuleConfig>(jsonStr); m_interval = JsonConvert.DeserializeObject <ModbusPushInterval>(jsonStr); if (m_interval == null) { m_interval = new ModbusPushInterval(DefaultPushInterval); } if (config.IsValidate()) { moduleHandle = await Slaves.ModuleHandle.CreateHandleFromConfiguration(config); if (moduleHandle != null) { var userContext = new Tuple <ModuleClient, Slaves.ModuleHandle>(ioTHubModuleClient, moduleHandle); // Register callback to be called when a message is received by the module await ioTHubModuleClient.SetInputMessageHandlerAsync( "input1", PipeMessage, userContext); m_task_list.Add(Start(userContext)); // Save the new existing config for reporting. m_existingConfig = config; } } } // Always report the change in properties. This keeps the reported properties in the module twin up to date even if none of the properties // actually change. It will also report the property changes if only the publish interval or slave configs change. ModuleTwinProperties moduleReportedProperties = new ModuleTwinProperties(m_interval?.PublishInterval, m_existingConfig); string reportedPropertiesJson = JsonConvert.SerializeObject(moduleReportedProperties); Console.WriteLine("Saving reported properties: " + reportedPropertiesJson); TwinCollection reportedProperties = new TwinCollection(reportedPropertiesJson); await ioTHubModuleClient.UpdateReportedPropertiesAsync(reportedProperties); }
public async Task UpdateReportedPropertiesAsync(TwinCollection reported) { await moduleClient.UpdateReportedPropertiesAsync(reported); }
static async Task IndexHueBridges(TwinCollection desiredProperties) { // Only proceed if the module twin contains a hueBridges key // TODO: exception handling in case of malformed JSON? if (desiredProperties.Contains("hueBridges")) { // Reset previous lists of sensors and lights hueSensors.Clear(); hueLights.Clear(); // Naive lookup through https://discovery.meethue.com IBridgeLocator locator = new HttpBridgeLocator(); IEnumerable<LocatedBridge> locatedLocalBridges = await locator.LocateBridgesAsync(TimeSpan.FromSeconds(5)); // Iterate over the bridge IDs and corresponding app key credentials provided in the module twin JArray moduleTwinBridges = desiredProperties["hueBridges"]; foreach (JObject bridge in moduleTwinBridges.Children()) { string moduleTwinBridgeId = bridge.GetValue("id").ToString(); string moduleTwinAppKey = bridge.GetValue("appKey").ToString(); // If a locally found bridge corresponds with a set of such credentials from the module twin, index it for sensors and lights IEnumerable<LocatedBridge> locatedBridgesInModuleTwinProperties = locatedLocalBridges.Where(locatedBridge => locatedBridge.BridgeId == moduleTwinBridgeId); if (locatedBridgesInModuleTwinProperties.Count() == 1) { LocatedBridge bridgeToIndex = locatedBridgesInModuleTwinProperties.First(); Console.WriteLine($"Will index Hue bridge with ID = {moduleTwinBridgeId} at IP {bridgeToIndex.IpAddress}, using App Key = {moduleTwinAppKey}"); LocalHueClient client = new LocalHueClient(bridgeToIndex.IpAddress, moduleTwinAppKey); try { // Index sensors IReadOnlyCollection<Sensor> sensors = await client.GetSensorsAsync(); foreach(Sensor sensor in sensors) { if (Enum.IsDefined(typeof(SensorType), sensor.Type)) { HueDeviceDescription sensorDescription = new HueDeviceDescription() { id = sensor.Id, uniqueId = sensor.UniqueId, }; hueSensors.Add(sensorDescription, new HueClientDescription(){client = client, ip = bridgeToIndex.IpAddress}); Console.WriteLine($"Found sensor: {sensor.Name} ({sensor.UniqueId})"); } } // Index lights IEnumerable<Light> lights = await client.GetLightsAsync(); foreach(Light light in lights) { hueLights.Add(light.Name); Console.WriteLine($"Found light: {light.Name} ({light.UniqueId})"); } } catch (Exception ex) { Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(ex.StackTrace); } } } // Report back the results of the indexing; the unique ID:s of each detected Hue device TwinCollection reportedProperties = new TwinCollection { ["Sensors"] = hueSensors.Keys.Select(sensorDescription => sensorDescription.uniqueId), ["Lights"] = hueLights }; await ioTHubModuleClient.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false); } }
/** * Initialize and Send DeviceInfo message */ public static async Task <GatewayController> Start(ModuleClient ioTHubModuleClient, Twin moduleTwin, CancellationToken cancelToken) { if (moduleTwin == null || moduleTwin.Properties == null) { throw new ArgumentOutOfRangeException("No module Twin desired properties provided."); } GatewayModel gatewayDeviceConfig = CreateGatewayModel(moduleTwin.Properties.Desired); GatewayController gatewayHandle = new GatewayController(gatewayDeviceConfig); DeviceProperties gatewayProperties = gatewayHandle.GatewayDeviceConfig.DeviceProperties; gatewayProperties.DeviceID = moduleTwin.ModuleId; // This is the place you can specify the metadata for your device. The below fields are not mandatory. gatewayProperties.UpdatedTime = DateTime.UtcNow.ToString(); gatewayProperties.FirmwareVersion = "1.0"; gatewayProperties.InstalledRAM = "Unknown"; gatewayProperties.Manufacturer = "Unknown"; gatewayProperties.ModelNumber = "Unknown"; gatewayProperties.Platform = RuntimeInformation.OSDescription; gatewayProperties.Processor = Enum.GetName(typeof(Architecture), RuntimeInformation.OSArchitecture); gatewayProperties.SerialNumber = "Unknown"; // Create send task await Task.Factory.StartNew(async() => { while (true) { if (gatewayHandle.GatewayConfig.ReportEnabledState) { bool hasMutex = false; try{ hasMutex = gatewayHandle.telemetryMutex.WaitOne(gatewayHandle.GatewayConfig.ReportingInterval); if (hasMutex) { if (gatewayHandle.Telemetry.Count > 0) // Send current telemetry data { gatewayHandle.SendData(ioTHubModuleClient, gatewayHandle.Telemetry); gatewayHandle.Telemetry.Clear(); } if (gatewayHandle.IsDeviceInfoUpdated) // Send DeviceInfo structure into module twin { string serializedStr = JsonConvert.SerializeObject(gatewayHandle.GatewayDeviceConfig); TwinCollection reported = JsonConvert.DeserializeObject <TwinCollection>(serializedStr); await ioTHubModuleClient.UpdateReportedPropertiesAsync(reported); gatewayHandle.IsDeviceInfoUpdated = false; } } else { Console.WriteLine("Error. Can't get mutext for telemetry data for {0} ms. Timeout!", gatewayHandle.GatewayConfig.ReportingInterval); } }catch (Exception ex) { Console.WriteLine("Error upload data: {0}, {1}", ex.Message, ex.StackTrace); } finally{ if (hasMutex) { gatewayHandle.telemetryMutex.ReleaseMutex(); } } } await Task.Delay(gatewayHandle.GatewayConfig.ReportingInterval); if (cancelToken.IsCancellationRequested) { // Cancel was called Console.WriteLine("Sending task canceled"); break; } } }, cancelToken); return(gatewayHandle); }