diff --git a/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs
index c0dedcff..35925012 100644
--- a/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs
+++ b/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs
@@ -144,6 +144,16 @@ namespace PepperDash.Essentials.Bridges
/// Reports the DHCP Status of the corresponding interface
///
public uint DhcpStatus { get; set; }
+
+ ///
+ /// Reports the current uptime. Updated in 5 minute intervals.
+ ///
+ public uint Uptime { get; set; }
+
+ ///
+ /// Reports the date of the last boot
+ ///
+ public uint LastBoot { get; set; }
#endregion
public SystemMonitorJoinMap()
@@ -157,6 +167,8 @@ namespace PepperDash.Essentials.Bridges
ControllerVersion = 5;
SerialNumber = 6;
Model = 7;
+ Uptime = 8;
+ LastBoot = 9;
ProgramStartJoin = 10;
@@ -179,6 +191,7 @@ namespace PepperDash.Essentials.Bridges
EthernetOffsetJoin = 15;
+ // Offset in groups of 15
HostName = 1;
CurrentIpAddress = 2;
CurrentSubnetMask = 3;
diff --git a/PepperDashEssentials/Bridges/SystemMonitorBridge.cs b/PepperDashEssentials/Bridges/SystemMonitorBridge.cs
index 96ab0a37..4764b12b 100644
--- a/PepperDashEssentials/Bridges/SystemMonitorBridge.cs
+++ b/PepperDashEssentials/Bridges/SystemMonitorBridge.cs
@@ -33,6 +33,8 @@ namespace PepperDash.Essentials.Bridges
systemMonitorController.ControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.ControllerVersion]);
systemMonitorController.SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumber]);
systemMonitorController.ModelFeedback.LinkInputSig(trilist.StringInput[joinMap.Model]);
+ systemMonitorController.UptimeFeedback.LinkInputSig(trilist.StringInput[joinMap.Uptime]);
+ systemMonitorController.LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot]);
// iterate the program status feedback collection and map all the joins
LinkProgramInfoJoins(systemMonitorController, trilist, joinMap);
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs
index 73a954ef..bbb1202d 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs
@@ -14,6 +14,12 @@ namespace PepperDash.Essentials.Core.Monitoring
///
public class SystemMonitorController : Device
{
+ private const long UptimePollTime = 300000;
+ private CTimer _uptimePollTimer;
+
+ private string _uptime;
+ private string _lastStart;
+
public event EventHandler SystemMonitorPropertiesChanged;
public Dictionary ProgramStatusFeedbackCollection;
@@ -31,6 +37,8 @@ namespace PepperDash.Essentials.Core.Monitoring
public StringFeedback SerialNumberFeedback { get; protected set; }
public StringFeedback ModelFeedback { get; set; }
+ public StringFeedback UptimeFeedback { get; set; }
+ public StringFeedback LastStartFeedback { get; set; }
public SystemMonitorController(string key)
: base(key)
@@ -49,6 +57,8 @@ namespace PepperDash.Essentials.Core.Monitoring
SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber);
ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName);
+ UptimeFeedback = new StringFeedback(() => _uptime);
+ LastStartFeedback = new StringFeedback(()=> _lastStart);
ProgramStatusFeedbackCollection = new Dictionary();
@@ -59,10 +69,52 @@ namespace PepperDash.Essentials.Core.Monitoring
}
CreateEthernetStatusFeedbacks();
+ UpdateEthernetStatusFeeedbacks();
+
+ _uptimePollTimer = new CTimer(PollUptime,null,0, UptimePollTime);
SystemMonitor.ProgramChange += SystemMonitor_ProgramChange;
SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange;
CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler;
+ CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironmentOnProgramStatusEventHandler;
+ }
+
+ private void CrestronEnvironmentOnProgramStatusEventHandler(eProgramStatusEventType programEventType)
+ {
+ if (programEventType != eProgramStatusEventType.Stopping) return;
+
+ _uptimePollTimer.Stop();
+ _uptimePollTimer.Dispose();
+ _uptimePollTimer = null;
+ }
+
+ private void PollUptime(object obj)
+ {
+ var consoleResponse = string.Empty;
+
+ CrestronConsole.SendControlSystemCommand("uptime", ref consoleResponse);
+
+ ParseUptime(consoleResponse);
+
+ UptimeFeedback.FireUpdate();
+ LastStartFeedback.FireUpdate();
+ }
+
+ private void ParseUptime(string response)
+ {
+ var splitString = response.Trim().Split('\r', '\n');
+
+ var lastStartRaw = splitString[2];
+ var lastStartIndex = lastStartRaw.IndexOf(':');
+
+ _lastStart = lastStartRaw.Substring(lastStartIndex + 1).Trim();
+
+ var uptimeRaw = splitString[0];
+
+ var forIndex = uptimeRaw.IndexOf("for", StringComparison.Ordinal);
+
+ //4 => "for " to get what's on the right
+ _uptime = uptimeRaw.Substring(forIndex + 4);
}
private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs)
@@ -86,6 +138,24 @@ namespace PepperDash.Essentials.Core.Monitoring
}
}
+ private void UpdateEthernetStatusFeeedbacks()
+ {
+ foreach (var iface in EthernetStatusFeedbackCollection)
+ {
+ iface.Value.CurrentIpAddressFeedback.FireUpdate();
+ iface.Value.CurrentSubnetMaskFeedback.FireUpdate();
+ iface.Value.CurrentDefaultGatewayFeedback.FireUpdate();
+ iface.Value.StaticIpAddressFeedback.FireUpdate();
+ iface.Value.StaticSubnetMaskFeedback.FireUpdate();
+ iface.Value.StaticDefaultGatewayFeedback.FireUpdate();
+ iface.Value.HostNameFeedback.FireUpdate();
+ iface.Value.DnsServerFeedback.FireUpdate();
+ iface.Value.DomainFeedback.FireUpdate();
+ iface.Value.DhcpStatusFeedback.FireUpdate();
+ iface.Value.MacAddressFeedback.FireUpdate();
+ }
+ }
+
///
/// Gets data in separate thread
///
@@ -332,62 +402,82 @@ namespace PepperDash.Essentials.Core.Monitoring
string response = null;
+ if (Program.RegistrationState == eProgramRegistrationState.Unregister || Program.OperatingState == eProgramOperatingState.Stop)
+ {
+ Debug.Console(2, "Program {0} not registered. Setting default values for program information.",
+ Program.Number);
+
+ ProgramInfo = new ProgramInfo(Program.Number)
+ {
+ OperatingState = Program.OperatingState,
+ RegistrationState = Program.RegistrationState
+ };
+
+ return;
+ }
+
var success = CrestronConsole.SendControlSystemCommand(
string.Format("progcomments:{0}", Program.Number), ref response);
- if (success)
- {
- //Debug.Console(2, "Progcomments Response: \r{0}", response);
-
- if (!response.ToLower().Contains("bad or incomplete"))
- {
- // Shared properteis
- ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n");
- ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n");
- ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n");
- ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n");
-
-
- if (ProgramInfo.ProgramFile.Contains(".dll"))
- {
- // SSP Program
- ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n");
- ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n");
- ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n");
- ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ",
- "\n");
- ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n");
- }
- else if (ProgramInfo.ProgramFile.Contains(".smw"))
- {
- // SIMPL Windows Program
- ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n");
- ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n");
- ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n");
- ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n");
- ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n");
- }
- //Debug.Console(2, "ProgramInfo: \r{0}", JsonConvert.SerializeObject(ProgramInfo));
- }
- else
- {
- Debug.Console(2,
- "Bad or incomplete console command response. Initializing ProgramInfo for slot: {0}",
- Program.Number);
-
- // Assume no valid program info. Constructing a new object will wipe all properties
- ProgramInfo = new ProgramInfo(Program.Number)
- {
- OperatingState = Program.OperatingState,
- RegistrationState = Program.RegistrationState
- };
- }
- }
- else
+ if (!success)
{
Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number);
+ UpdateFeedbacks();
+ return;
}
+ if (response.ToLower().Contains("bad or incomplete"))
+ {
+ Debug.Console(2,
+ "Program in slot {0} not running. Setting default ProgramInfo for slot: {0}",
+ Program.Number);
+
+ // Assume no valid program info. Constructing a new object will wipe all properties
+ ProgramInfo = new ProgramInfo(Program.Number)
+ {
+ OperatingState = Program.OperatingState,
+ RegistrationState = Program.RegistrationState
+ };
+
+ UpdateFeedbacks();
+
+ return;
+ }
+
+
+ // Shared properteis
+ ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n");
+ ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n");
+ ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n");
+ ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n");
+
+
+ if (ProgramInfo.ProgramFile.Contains(".dll"))
+ {
+ // SSP Program
+ ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n");
+ ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n");
+ ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n");
+ ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ",
+ "\n");
+ ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n");
+ }
+ else if (ProgramInfo.ProgramFile.Contains(".smw"))
+ {
+ // SIMPL Windows Program
+ ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n");
+ ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n");
+ ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n");
+ ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n");
+ ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n");
+ }
+ Debug.Console(2, "Program info for slot {0} successfully updated", Program.Number);
+
+ UpdateFeedbacks();
+ }
+
+ private void UpdateFeedbacks()
+ {
ProgramNameFeedback.FireUpdate();
ProgramCompileTimeFeedback.FireUpdate();
CrestronDataBaseVersionFeedback.FireUpdate();