Skip to content

Commit

Permalink
XML docs and comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
markwaterman committed Mar 10, 2023
1 parent 97462fa commit d472e2f
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Scaleout.DigitalTwin.Hosting" Version="3.8.0" />
<PackageReference Include="Scaleout.DigitalTwin.Hosting" Version="3.8.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public override ProcessingResult ProcessMessages(ProcessingContext context, Real
foreach (var msg in newMessages)
{
digitalTwin.Temperature = msg.Temperature;
if (digitalTwin.Temperature > TemperatureRange.High)
if (digitalTwin.Temperature > TemperatureRange.NormalOperationMax)
{
// Overheating. Issue a shutdown command to the device:
var cmd = new DeviceCommandMessage { CommandText = "shutdown" };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

namespace RealTimeWindTurbine
{
/// <summary>
/// Model holding that holds state for a simulated
/// digital twin instance.
/// </summary>
public class RealTimeWindTurbineModel : DigitalTwinBase
{
public int Temperature { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Scaleout.DigitalTwin.Hosting" Version="3.8.0" />
<PackageReference Include="Scaleout.DigitalTwin.Hosting" Version="3.8.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,22 @@

namespace SimulatedWindTurbine
{
/// <summary>
/// Handles messages sent from the real-time digital twin.
/// </summary>
/// <remarks>
/// Messages sent here originate from ProcessingContext.SendToDataSource() calls made
/// in the RealTimeWindTurbineMessageProcessor. The WindTurbineSimulationModel
/// in this SimulatedWindTurbine project is simulating a data source (a real-world device),
/// so when a real-time model sends a message back to its data source during a simulation run,
/// the message arrives here.
/// </remarks>
public class WindTurbineSimulationMessageProcessor : MessageProcessor<WindTurbineSimulationModel, DeviceCommandMessage>
{
public override ProcessingResult ProcessMessages(ProcessingContext context, WindTurbineSimulationModel digitalTwin, IEnumerable<DeviceCommandMessage> newMessages)
{
ProcessingResult result = ProcessingResult.NoUpdate;

try
{
// Process incoming messages
Expand All @@ -22,6 +34,13 @@ public override ProcessingResult ProcessMessages(ProcessingContext context, Wind
{
case "shutdown":
digitalTwin.State = TurbineState.Idle;
// We've modified the digital twin instance, so return DoUpdate to save its state in the
// ScaleOut service.
result = ProcessingResult.DoUpdate;
break;
case "start":
digitalTwin.State = TurbineState.Running;
result = ProcessingResult.DoUpdate;
break;
default:
context.LogMessage(LogSeverity.Error,
Expand All @@ -38,15 +57,12 @@ public override ProcessingResult ProcessMessages(ProcessingContext context, Wind
catch (Exception ex)
{
// Catch all exceptions and log them using the embedded logger.
// If the ScaleOut Digital Twin Streaming Service is used to host real-time digital twins,
// you can see both trace messages and logged exceptions on the Manage Digital Twin Model page.
context.LogMessage(LogSeverity.Error,
string.Format("Exception occurred while processing new messages for the real-time digital twin object '{0}'. Details: {1}",
digitalTwin.Id, ex.Message));
}

// Return ProcessingResult.DoUpdate since this method modified the state of the digitalTwin instance.
return ProcessingResult.DoUpdate;
return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ public class WindTurbineSimulationModel : DigitalTwinBase
{
/// <summary>
/// Get's the simulated temperature at this time interval. Call
/// <see cref="NextState"/> to move this instance to the next time
/// <see cref="AdvanceToNextState"/> to move this instance to the next time
/// interval.
/// </summary>
public int Temperature { get; set; } = TemperatureRange.NormalOperation;
public int Temperature { get; set; } = TemperatureRange.NormalOperationMin;

public TurbineState State { get; set; } = TurbineState.Running;

Expand All @@ -36,7 +36,7 @@ public class WindTurbineSimulationModel : DigitalTwinBase
/// <summary>
/// Moves that state of the simulation instance to its next time slice.
/// </summary>
public void NextState()
public void AdvanceToNextState()
{
switch (State)
{
Expand All @@ -45,19 +45,19 @@ public void NextState()
{
// Transition to Overheating state.
State = TurbineState.Overheating;
Temperature = _rand.Next(TemperatureRange.High, TemperatureRange.MaxHigh);
Temperature = _rand.Next(TemperatureRange.NormalOperationMax, TemperatureRange.OverheatMax);
}
else
{
Temperature = _rand.Next(TemperatureRange.NormalOperation, TemperatureRange.High);
Temperature = _rand.Next(TemperatureRange.NormalOperationMin, TemperatureRange.NormalOperationMax);
}
break;
case TurbineState.Overheating:
// Continue overheating.
Temperature = _rand.Next(TemperatureRange.High, TemperatureRange.MaxHigh);
Temperature = _rand.Next(TemperatureRange.NormalOperationMax, TemperatureRange.OverheatMax);
break;
case TurbineState.Idle:
Temperature = TemperatureRange.NormalOperation;
Temperature = TemperatureRange.Idle;
break;
default:
throw new NotSupportedException($"Unexpected turbine state {State}.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,27 @@

namespace SimulatedWindTurbine
{
/// <summary>
/// Simulation processor that gets triggered for every time interval in a simulation.
/// </summary>
public class WindTurbineSimulationProcessor : SimulationProcessor<WindTurbineSimulationModel>
{
/// <summary>
/// This method is called by the service when the next simulation
/// interval has elapsed. Use it to update a simulation's state to reflect the
/// given time interval and send any desired telemetry to the real-time digital twin.
/// </summary>
/// <param name="context">The digital twin simulation processing context.</param>
/// <param name="digitalTwin">The target digital twin object.</param>
/// <param name="currentTime">The current simulation time.</param>
/// <returns>
/// <see cref="ProcessingResult.DoUpdate"/> when the digital twin object needs to be updated, and
/// <see cref="ProcessingResult.NoUpdate"/> when no updates are needed.
/// </returns>
public override ProcessingResult ProcessModel(ProcessingContext context, WindTurbineSimulationModel digitalTwin, DateTimeOffset currentTime)
{

digitalTwin.NextState();
digitalTwin.AdvanceToNextState();
var msg = new TemperatureReading
{
Temperature = digitalTwin.Temperature,
Expand All @@ -25,7 +40,7 @@ public override ProcessingResult ProcessModel(ProcessingContext context, WindTur

context.SimulationController.EmitTelemetry("RealTimeWindTurbine", msgBytes);

// The digitalTwin.NextState() call modified the instance,
// The digitalTwin.AdvanceToNextState() call modified the instance,
// so we return DoUpdate to ensure that the simulation instance
// is updated in the ScaleOut service.
return ProcessingResult.DoUpdate;
Expand Down
9 changes: 7 additions & 2 deletions DotNetCore/sim-rtdt/WindTurbine/UnitTests/UnitTest1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using WindTurbineMessages;
using Scaleout.Client;
using Scaleout.DigitalTwin.Client;
using SimulatedWindTurbine;
using Scaleout.Streaming.DigitalTwin.Core;

namespace UnitTests
{
Expand Down Expand Up @@ -42,13 +44,16 @@ public void CreateSimulationInstance()
var conn = GridConnection.Connect("hosts=localhost:721");
var dtEndpoint = new DigitalTwinModelEndpoint(conn, "SimulatedWindTurbine");

// Create a new simulation instance in the ScaleOut service with specified state.
var simTwin = new SimulatedWindTurbine.WindTurbineSimulationModel
{
Temperature = 60,
FailureRate = 100
};
dtEndpoint.CreateTwin($"simeTwin1", simTwin);

var sendRes = dtEndpoint.CreateTwin($"simTwin1", simTwin);
Assert.Equal(SendingResult.Handled, sendRes);
}


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@

namespace WindTurbineMessages
{
/// <summary>
/// Message sent from a real-time digital twin to a device or, in this case,
/// a simulation digital twin like the SimulatedWindTurbine project.
/// </summary>
public class DeviceCommandMessage
{
/// <summary>
/// Command to issue to a device. The simulated wind turbine supports
/// "start" and "shutdown".
/// </summary>
public string CommandText { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@

namespace WindTurbineMessages
{
/// <summary>
/// Ranges used for generating random WindTurbine gearbox temperature readings.
/// </summary>
public class TemperatureRange
{
public static readonly int Idle = 20;
public static readonly int NormalOperation = 100;
public static readonly int High = 150;
public static readonly int MaxHigh = 200;
public static readonly int NormalOperationMin = 100;
public static readonly int NormalOperationMax = 150;
public static readonly int OverheatMax = 200;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@
<Version>1.4.0</Version>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="JsonSubTypes" Version="2.0.1" />
</ItemGroup>

</Project>

0 comments on commit d472e2f

Please sign in to comment.