adds Uptime and LastBoot console parsing and reporting

* refactored ProgramInfo routine to not send console commands for unregistered or stopped programs and inverted some if statements
This commit is contained in:
Andrew Welker
2020-03-25 14:21:41 -06:00
parent 93e542befd
commit e2fe8834c5
3 changed files with 154 additions and 49 deletions

View File

@@ -144,6 +144,16 @@ namespace PepperDash.Essentials.Bridges
/// Reports the DHCP Status of the corresponding interface
/// </summary>
public uint DhcpStatus { get; set; }
/// <summary>
/// Reports the current uptime. Updated in 5 minute intervals.
/// </summary>
public uint Uptime { get; set; }
/// <summary>
/// Reports the date of the last boot
/// </summary>
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;

View File

@@ -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);

View File

@@ -14,6 +14,12 @@ namespace PepperDash.Essentials.Core.Monitoring
/// </summary>
public class SystemMonitorController : Device
{
private const long UptimePollTime = 300000;
private CTimer _uptimePollTimer;
private string _uptime;
private string _lastStart;
public event EventHandler<EventArgs> SystemMonitorPropertiesChanged;
public Dictionary<uint, ProgramStatusFeedbacks> 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<uint, ProgramStatusFeedbacks>();
@@ -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();
}
}
/// <summary>
/// Gets data in separate thread
/// </summary>
@@ -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();