Skip to content

Commit

Permalink
Adding SendData and SendInterval Twin Configuration to Simulated Temp… (
Browse files Browse the repository at this point in the history
#729)

* Adding SendData and SendInterval Twin Configuration to Simulated Temperature Sensor.

* Fixing StyleCop.
  • Loading branch information
aribeironovaes authored Jan 18, 2019
1 parent 1fe00e8 commit 7dc7041
Showing 1 changed file with 74 additions and 24 deletions.
98 changes: 74 additions & 24 deletions edge-modules/SimulatedTemperatureSensor/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace SimulatedTemperatureSensor
using Microsoft.Azure.Devices.Edge.Util;
using Microsoft.Azure.Devices.Edge.Util.Concurrency;
using Microsoft.Azure.Devices.Edge.Util.TransientFaultHandling;
using Microsoft.Azure.Devices.Shared;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using ExponentialBackoff = Microsoft.Azure.Devices.Edge.Util.TransientFaultHandling.ExponentialBackoff;
Expand All @@ -21,6 +22,9 @@ class Program
{
const int RetryCount = 5;
const string MessageCountConfigKey = "MessageCount";
const string SendDataConfigKey = "SendData";
const string SendIntervalConfigKey = "SendInterval";

static readonly ITransientErrorDetectionStrategy TimeoutErrorDetectionStrategy = new DelegateErrorDetectionStrategy(ex => ex.HasTimeoutException());

static readonly RetryStrategy TransientRetryStrategy =
Expand All @@ -30,6 +34,9 @@ class Program
static readonly AtomicBoolean Reset = new AtomicBoolean(false);
static readonly Guid BatchId = Guid.NewGuid();

static TimeSpan messageDelay;
static bool sendData = true;

public enum ControlCommandEnum
{
Reset = 0,
Expand All @@ -48,7 +55,7 @@ static async Task<int> MainAsync()
.AddEnvironmentVariables()
.Build();

TimeSpan messageDelay = configuration.GetValue("MessageDelay", TimeSpan.FromSeconds(5));
messageDelay = configuration.GetValue("MessageDelay", TimeSpan.FromSeconds(5));
int messageCount = configuration.GetValue(MessageCountConfigKey, 500);
bool sendForever = messageCount < 0;
var sim = new SimulatorParameters
Expand Down Expand Up @@ -81,11 +88,27 @@ static async Task<int> MainAsync()
ModuleClient moduleClient = await retryPolicy.ExecuteAsync(() => InitModuleClient(transportType));

ModuleClient userContext = moduleClient;
Twin currentTwinProperties = await moduleClient.GetTwinAsync();
if (currentTwinProperties.Properties.Desired.Contains(SendIntervalConfigKey))
{
messageDelay = TimeSpan.FromSeconds((int)currentTwinProperties.Properties.Desired[SendIntervalConfigKey]);
}

if (currentTwinProperties.Properties.Desired.Contains(SendDataConfigKey))
{
sendData = (bool)currentTwinProperties.Properties.Desired[SendDataConfigKey];
if (!sendData)
{
Console.WriteLine("Sending data disabled. Change twin configuration to start sending again.");
}
}

await moduleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertiesUpdated, userContext);
await moduleClient.SetInputMessageHandlerAsync("control", ControlMessageHandle, userContext);

(CancellationTokenSource cts, ManualResetEventSlim completed, Option<object> handler)
= ShutdownHandler.Init(TimeSpan.FromSeconds(5), null);
await SendEvents(moduleClient, messageDelay, sendForever, messageCount, sim, cts);
await SendEvents(moduleClient, sendForever, messageCount, sim, cts);
await cts.Token.WhenCanceled();
completed.Set();
handler.ForEach(h => GC.KeepAlive(h));
Expand Down Expand Up @@ -187,7 +210,6 @@ static Task<MethodResponse> ResetMethod(MethodRequest methodRequest, object user
/// </summary>
static async Task SendEvents(
ModuleClient moduleClient,
TimeSpan messageDelay,
bool sendForever,
int messageCount,
SimulatorParameters sim,
Expand All @@ -214,30 +236,34 @@ static async Task SendEvents(
currentTemp += -0.25 + (Rnd.NextDouble() * 1.5); // add value between [-0.25..1.25] - average +0.5
}

var tempData = new MessageBody
if (sendData)
{
Machine = new Machine
var tempData = new MessageBody
{
Temperature = currentTemp,
Pressure = sim.MachinePressureMin + ((currentTemp - sim.MachineTempMin) * normal),
},
Ambient = new Ambient
{
Temperature = sim.AmbientTemp + Rnd.NextDouble() - 0.5,
Humidity = Rnd.Next(24, 27)
},
TimeCreated = DateTime.UtcNow
};

string dataBuffer = JsonConvert.SerializeObject(tempData);
var eventMessage = new Message(Encoding.UTF8.GetBytes(dataBuffer));
eventMessage.Properties.Add("sequenceNumber", count.ToString());
eventMessage.Properties.Add("batchId", BatchId.ToString());
Console.WriteLine($"\t{DateTime.Now.ToLocalTime()}> Sending message: {count}, Body: [{dataBuffer}]");

await moduleClient.SendEventAsync("temperatureOutput", eventMessage);
Machine = new Machine
{
Temperature = currentTemp,
Pressure = sim.MachinePressureMin + ((currentTemp - sim.MachineTempMin) * normal),
},
Ambient = new Ambient
{
Temperature = sim.AmbientTemp + Rnd.NextDouble() - 0.5,
Humidity = Rnd.Next(24, 27)
},
TimeCreated = DateTime.UtcNow
};

string dataBuffer = JsonConvert.SerializeObject(tempData);
var eventMessage = new Message(Encoding.UTF8.GetBytes(dataBuffer));
eventMessage.Properties.Add("sequenceNumber", count.ToString());
eventMessage.Properties.Add("batchId", BatchId.ToString());
Console.WriteLine($"\t{DateTime.Now.ToLocalTime()}> Sending message: {count}, Body: [{dataBuffer}]");

await moduleClient.SendEventAsync("temperatureOutput", eventMessage);
count++;
}

await Task.Delay(messageDelay, cts.Token);
count++;
}

if (messageCount < count)
Expand All @@ -246,6 +272,30 @@ static async Task SendEvents(
}
}

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.
}

static void CancelProgram(CancellationTokenSource cts)
{
Console.WriteLine("Termination requested, closing.");
Expand Down

0 comments on commit 7dc7041

Please sign in to comment.