Add desired property Config.SetPointTemp and Config.TelemetryInterval
Expected behavior when desired.Config.SetPointTemp updated: 1. The mid-point (or average value) of temperature was updated 2. The reported property sharing the same name was update Expected behavior when desired.Config.TelemetryInterval updated: 1. The telemetry interval (a.k.a. report interval) was updated (unit: seconds) 2. The reported property sharing the same name was update Both the two desired properties will be persisted on the IoT Hub. So the effect will always be there, no matter the simulator was reboot or not, except the property was removed manually. Then it will use the default value: SetPointTemp: 34.5 TelemetryInterval: 5 second
This commit is contained in:
Родитель
918396ffb8
Коммит
799c1210e4
|
@ -96,7 +96,7 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Common.SampleDat
|
||||||
}
|
}
|
||||||
|
|
||||||
public SampleDataGenerator(double minValueToGenerate, double maxNonPeakValueToGenerate)
|
public SampleDataGenerator(double minValueToGenerate, double maxNonPeakValueToGenerate)
|
||||||
: this (minValueToGenerate, maxNonPeakValueToGenerate, 0, 0, new RandomGenerator())
|
: this(minValueToGenerate, maxNonPeakValueToGenerate, 0, 0, new RandomGenerator())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +132,11 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Common.SampleDat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double GetMidPointOfRange()
|
||||||
|
{
|
||||||
|
return (_minValueToGenerate + _maxNonPeakValueToGenerate) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
private void GetNextRawValue()
|
private void GetNextRawValue()
|
||||||
{
|
{
|
||||||
double adjustment = ((2.0 * _deltaValue) * _randomGenerator.GetRandomDouble()) - _deltaValue;
|
double adjustment = ((2.0 * _deltaValue) * _randomGenerator.GetRandomDouble()) - _deltaValue;
|
||||||
|
|
|
@ -10,6 +10,7 @@ using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.Sim
|
||||||
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Devices;
|
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Devices;
|
||||||
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Devices.DMTasks;
|
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Devices.DMTasks;
|
||||||
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Logging;
|
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Logging;
|
||||||
|
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Telemetry;
|
||||||
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Telemetry.Factory;
|
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Telemetry.Factory;
|
||||||
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Transport.Factory;
|
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.SimulatorCore.Transport.Factory;
|
||||||
using Microsoft.Azure.Devices.Client;
|
using Microsoft.Azure.Devices.Client;
|
||||||
|
@ -29,6 +30,8 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
ITelemetryFactory telemetryFactory, IConfigurationProvider configurationProvider)
|
ITelemetryFactory telemetryFactory, IConfigurationProvider configurationProvider)
|
||||||
: base(logger, transportFactory, telemetryFactory, configurationProvider)
|
: base(logger, transportFactory, telemetryFactory, configurationProvider)
|
||||||
{
|
{
|
||||||
|
_desiredPropertyUdateHandlers.Add(SetPointTempPropertyName, OnSetPointTempUpdate);
|
||||||
|
_desiredPropertyUdateHandlers.Add(TelemetryIntervalPropertyName, OnTelemetryIntervalUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -75,7 +78,7 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
public void ChangeSetPointTemp(double setPointTemp)
|
public void ChangeSetPointTemp(double setPointTemp)
|
||||||
{
|
{
|
||||||
var remoteMonitorTelemetry = (RemoteMonitorTelemetry)_telemetryController;
|
var remoteMonitorTelemetry = (RemoteMonitorTelemetry)_telemetryController;
|
||||||
remoteMonitorTelemetry.ChangeSetPointTemperature(setPointTemp);
|
remoteMonitorTelemetry.SetPointTemperature = setPointTemp;
|
||||||
Logger.LogInfo("Device {0} temperature changed to {1}", DeviceID, setPointTemp);
|
Logger.LogInfo("Device {0} temperature changed to {1}", DeviceID, setPointTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,5 +275,21 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
}
|
}
|
||||||
await Transport.UpdateReportedPropertiesAsync(collection);
|
await Transport.UpdateReportedPropertiesAsync(collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async Task OnSetPointTempUpdate(object value)
|
||||||
|
{
|
||||||
|
var telemetry = _telemetryController as ITelemetryWithSetPointTemperature;
|
||||||
|
telemetry.SetPointTemperature = Convert.ToDouble(value);
|
||||||
|
|
||||||
|
await SetReportedPropertyAsync(SetPointTempPropertyName, telemetry.SetPointTemperature);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task OnTelemetryIntervalUpdate(object value)
|
||||||
|
{
|
||||||
|
var telemetry = _telemetryController as ITelemetryWithInterval;
|
||||||
|
telemetry.TelemetryIntervalInSeconds = Convert.ToInt32(value);
|
||||||
|
|
||||||
|
await SetReportedPropertyAsync(TelemetryIntervalPropertyName, telemetry.TelemetryIntervalInSeconds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ using Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.Sim
|
||||||
|
|
||||||
namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.Cooler.Telemetry
|
namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob.Cooler.Telemetry
|
||||||
{
|
{
|
||||||
public class RemoteMonitorTelemetry : ITelemetry
|
public class RemoteMonitorTelemetry : ITelemetry, ITelemetryWithInterval, ITelemetryWithSetPointTemperature
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly string _deviceId;
|
private readonly string _deviceId;
|
||||||
|
@ -37,6 +37,8 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
_temperatureGenerator = new SampleDataGenerator(33, 36, 42, peakFrequencyInTicks);
|
_temperatureGenerator = new SampleDataGenerator(33, 36, 42, peakFrequencyInTicks);
|
||||||
_humidityGenerator = new SampleDataGenerator(20, 50);
|
_humidityGenerator = new SampleDataGenerator(20, 50);
|
||||||
_externalTemperatureGenerator = new SampleDataGenerator(-20, 120);
|
_externalTemperatureGenerator = new SampleDataGenerator(-20, 120);
|
||||||
|
|
||||||
|
TelemetryIntervalInSeconds = REPORT_FREQUENCY_IN_SECONDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendEventsAsync(CancellationToken token, Func<object, Task> sendMessageAsync)
|
public async Task SendEventsAsync(CancellationToken token, Func<object, Task> sendMessageAsync)
|
||||||
|
@ -67,13 +69,23 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
|
|
||||||
await sendMessageAsync(monitorData);
|
await sendMessageAsync(monitorData);
|
||||||
}
|
}
|
||||||
await Task.Delay(TimeSpan.FromSeconds(REPORT_FREQUENCY_IN_SECONDS), token);
|
await Task.Delay(TimeSpan.FromSeconds(TelemetryIntervalInSeconds), token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeSetPointTemperature(double newSetPointTemperature)
|
public int TelemetryIntervalInSeconds { get; set; }
|
||||||
|
|
||||||
|
public double SetPointTemperature
|
||||||
{
|
{
|
||||||
_temperatureGenerator.ShiftSubsequentData(newSetPointTemperature);
|
get
|
||||||
|
{
|
||||||
|
return _temperatureGenerator.GetMidPointOfRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_temperatureGenerator.ShiftSubsequentData(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,6 +29,8 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
public const string StartupTimePropertyName = "StartupTime";
|
public const string StartupTimePropertyName = "StartupTime";
|
||||||
public const string FirmwareVersionPropertyName = "FirmwareVersion";
|
public const string FirmwareVersionPropertyName = "FirmwareVersion";
|
||||||
public const string ConfigurationVersionPropertyName = "ConfigurationVersion";
|
public const string ConfigurationVersionPropertyName = "ConfigurationVersion";
|
||||||
|
public const string SetPointTempPropertyName = "Config.SetPointTemp";
|
||||||
|
public const string TelemetryIntervalPropertyName = "Config.TelemetryInterval";
|
||||||
|
|
||||||
// pointer to the currently executing event group
|
// pointer to the currently executing event group
|
||||||
private int _currentEventGroup = 0;
|
private int _currentEventGroup = 0;
|
||||||
|
@ -168,10 +170,7 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Transport.OpenAsync();
|
await InitializeAsync();
|
||||||
await UpdateReportedPropertiesAsync();
|
|
||||||
|
|
||||||
SetMethodHandlers();
|
|
||||||
|
|
||||||
var loopTasks = new List<Task>
|
var loopTasks = new List<Task>
|
||||||
{
|
{
|
||||||
|
@ -191,6 +190,16 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task InitializeAsync()
|
||||||
|
{
|
||||||
|
await Transport.OpenAsync();
|
||||||
|
SetupCallbacks();
|
||||||
|
|
||||||
|
var twin = await Transport.GetTwinAsync();
|
||||||
|
await UpdateReportedPropertiesAsync(twin.Properties.Reported);
|
||||||
|
await OnDesiredPropertyUpdate(twin.Properties.Desired, null);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Iterates through the list of IEventGroups and fires off the events in a given event group before moving to the next.
|
/// Iterates through the list of IEventGroups and fires off the events in a given event group before moving to the next.
|
||||||
/// If RepeatEventListForever is true the device will continue to loop through each event group, if false
|
/// If RepeatEventListForever is true the device will continue to loop through each event group, if false
|
||||||
|
@ -351,14 +360,12 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
Logger.LogInfo("********** Processing Device {0} has been cancelled - StartReceiveLoopAsync Ending. **********", DeviceID);
|
Logger.LogInfo("********** Processing Device {0} has been cancelled - StartReceiveLoopAsync Ending. **********", DeviceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task UpdateReportedPropertiesAsync(bool regenerate = false)
|
protected async Task UpdateReportedPropertiesAsync(TwinCollection reported, bool regenerate = false)
|
||||||
{
|
{
|
||||||
var reported = await Transport.GetReportedPropertiesAsync();
|
|
||||||
|
|
||||||
var patch = new TwinCollection();
|
var patch = new TwinCollection();
|
||||||
CrossSyncProperties(patch, reported, regenerate);
|
CrossSyncProperties(patch, reported, regenerate);
|
||||||
AddSupportedMethods(patch, reported);
|
AddSupportedMethods(patch, reported);
|
||||||
patch.Set(StartupTimePropertyName, DateTime.UtcNow.ToString());
|
AddConfigs(patch);
|
||||||
|
|
||||||
// Update ReportedProperties to IoT Hub
|
// Update ReportedProperties to IoT Hub
|
||||||
await Transport.UpdateReportedPropertiesAsync(patch);
|
await Transport.UpdateReportedPropertiesAsync(patch);
|
||||||
|
@ -454,13 +461,58 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
patch["SupportedMethods"] = supportedMethods;
|
patch["SupportedMethods"] = supportedMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetMethodHandlers()
|
protected void AddConfigs(TwinCollection patch)
|
||||||
|
{
|
||||||
|
var telemetryWithInterval = _telemetryController as ITelemetryWithInterval;
|
||||||
|
if (telemetryWithInterval != null)
|
||||||
|
{
|
||||||
|
patch.Set(TelemetryIntervalPropertyName, telemetryWithInterval.TelemetryIntervalInSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
var telemetryWithSetPointTemp = _telemetryController as ITelemetryWithSetPointTemperature;
|
||||||
|
if (telemetryWithSetPointTemp != null)
|
||||||
|
{
|
||||||
|
patch.Set(SetPointTempPropertyName, telemetryWithSetPointTemp.SetPointTemperature);
|
||||||
|
}
|
||||||
|
|
||||||
|
patch.Set(StartupTimePropertyName, DateTime.UtcNow.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupCallbacks()
|
||||||
{
|
{
|
||||||
foreach (var method in Commands.Where(c => c.DeliveryType == DeliveryType.Method))
|
foreach (var method in Commands.Where(c => c.DeliveryType == DeliveryType.Method))
|
||||||
{
|
{
|
||||||
var callback = GetType().GetMethod($"On{method.Name}").CreateDelegate(typeof(MethodCallback), this) as MethodCallback;
|
try
|
||||||
|
{
|
||||||
|
var handler = GetType().GetMethod($"On{method.Name}").CreateDelegate(typeof(MethodCallback), this) as MethodCallback;
|
||||||
|
|
||||||
Transport.SetMethodHandler(method.Name, callback);
|
Transport.SetMethodHandler(method.Name, handler);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError($"Exception raised while adding callback for method {method.Name}: {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Transport.SetDesiredPropertyUpdateCallback(OnDesiredPropertyUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnDesiredPropertyUpdate(TwinCollection desiredProperties, object userContext)
|
||||||
|
{
|
||||||
|
foreach (var pair in desiredProperties.AsEnumerableFlatten())
|
||||||
|
{
|
||||||
|
Func<object, Task> handler;
|
||||||
|
if (_desiredPropertyUdateHandlers.TryGetValue(pair.Key, out handler))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await handler(pair.Value.Value.Value);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError($"Exception raised while processing desired property {pair.Key} change: {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,14 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
/// <returns>Task that completes when all tasks are sent</returns>
|
/// <returns>Task that completes when all tasks are sent</returns>
|
||||||
Task SendEventsAsync(CancellationToken token, Func<object, Task> sendMessageAsync);
|
Task SendEventsAsync(CancellationToken token, Func<object, Task> sendMessageAsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ITelemetryWithInterval
|
||||||
|
{
|
||||||
|
int TelemetryIntervalInSeconds { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITelemetryWithSetPointTemperature
|
||||||
|
{
|
||||||
|
double SetPointTemperature { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,17 +94,21 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
await Task.FromResult(0);
|
await Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TwinCollection> GetReportedPropertiesAsync()
|
public async Task<Twin> GetTwinAsync()
|
||||||
{
|
{
|
||||||
_logger.LogInfo("GetReportedPropertiesAsync called");
|
_logger.LogInfo("GetTwinAsync called");
|
||||||
|
|
||||||
return await Task.FromResult(new TwinCollection());
|
return await Task.FromResult(new Twin());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMethodHandler(string methodName, MethodCallback callback)
|
public void SetMethodHandler(string methodName, MethodCallback callback)
|
||||||
{
|
{
|
||||||
_logger.LogInfo("SetMethodHandler called:");
|
_logger.LogInfo($"SetMethodHandler called: {methodName} -> {callback.Method.Name}");
|
||||||
_logger.LogInfo($"SetMethodHandler: methodName: {methodName}");
|
}
|
||||||
|
|
||||||
|
public void SetDesiredPropertyUpdateCallback(DesiredPropertyUpdateCallback callback)
|
||||||
|
{
|
||||||
|
_logger.LogInfo($"SetDesiredPropertyUpdateCallback called, callback = {callback.Method.Name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,10 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
|
|
||||||
Task UpdateReportedPropertiesAsync(TwinCollection reportedProperties);
|
Task UpdateReportedPropertiesAsync(TwinCollection reportedProperties);
|
||||||
|
|
||||||
Task<TwinCollection> GetReportedPropertiesAsync();
|
Task<Twin> GetTwinAsync();
|
||||||
|
|
||||||
void SetMethodHandler(string methodName, MethodCallback callback);
|
void SetMethodHandler(string methodName, MethodCallback callback);
|
||||||
|
|
||||||
|
void SetDesiredPropertyUpdateCallback(DesiredPropertyUpdateCallback callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,10 +285,9 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
await _deviceClient.UpdateReportedPropertiesAsync(reportedProperties);
|
await _deviceClient.UpdateReportedPropertiesAsync(reportedProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TwinCollection> GetReportedPropertiesAsync()
|
public async Task<Twin> GetTwinAsync()
|
||||||
{
|
{
|
||||||
var twin = await _deviceClient.GetTwinAsync();
|
return await _deviceClient.GetTwinAsync();
|
||||||
return twin.Properties.Reported;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMethodHandler(string methodName, MethodCallback callback)
|
public void SetMethodHandler(string methodName, MethodCallback callback)
|
||||||
|
@ -296,6 +295,11 @@ namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.Simulator.WebJob
|
||||||
_deviceClient.SetMethodHandler(methodName, callback, null);
|
_deviceClient.SetMethodHandler(methodName, callback, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetDesiredPropertyUpdateCallback(DesiredPropertyUpdateCallback callback)
|
||||||
|
{
|
||||||
|
_deviceClient.SetDesiredPropertyUpdateCallback(callback, null);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implement the IDisposable interface in order to close the device manager
|
/// Implement the IDisposable interface in order to close the device manager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче