adds bridging for all ethernet parameters

This commit is contained in:
Andrew Welker
2020-03-25 10:13:29 -06:00
parent 3852617270
commit 93e542befd
3 changed files with 241 additions and 79 deletions

View File

@@ -9,11 +9,21 @@ namespace PepperDash.Essentials.Bridges
/// </summary> /// </summary>
public uint ProgramStartJoin { get; set; } public uint ProgramStartJoin { get; set; }
/// <summary>
/// Offset to indicate where the range of iterated Ethernet joins will start
/// </summary>
public uint EthernetStartJoin { get; set; }
/// <summary> /// <summary>
/// Offset between each program join set /// Offset between each program join set
/// </summary> /// </summary>
public uint ProgramOffsetJoin { get; set; } public uint ProgramOffsetJoin { get; set; }
/// <summary>
/// Offset between each Ethernet Interface join set
/// </summary>
public uint EthernetOffsetJoin { get; set; }
#region Digitals #region Digitals
/// <summary> /// <summary>
/// Range Sets and reports whether the corresponding program slot is started /// Range Sets and reports whether the corresponding program slot is started
@@ -82,6 +92,58 @@ namespace PepperDash.Essentials.Bridges
/// Serialized JSON output that aggregates the program info of the corresponding program /// Serialized JSON output that aggregates the program info of the corresponding program
/// </summary> /// </summary>
public uint AggregatedProgramInfo { get; set; } public uint AggregatedProgramInfo { get; set; }
/// <summary>
/// Reports the controller serial number
/// </summary>
public uint SerialNumber { get; set; }
/// <summary>
/// Reports the controller model
/// </summary>
public uint Model { get; set; }
/// <summary>
/// Reports the Host name set on the corresponding interface
/// </summary>
public uint HostName { get; set; }
/// <summary>
/// Reports the Current IP address set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned address.
/// </summary>
public uint CurrentIpAddress { get; set; }
/// <summary>
/// Reporst the Current Default Gateway set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned gateway
/// </summary>
public uint CurrentDefaultGateway { get; set; }
/// <summary>
/// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask
/// </summary>
public uint CurrentSubnetMask { get; set; }
/// <summary>
/// Reports the Static IP address set on the corresponding interface. If DHCP is disabled, this will match the Current IP address
/// </summary>
public uint StaticIpAddress { get; set; }
/// <summary>
/// Reporst the Static Default Gateway set on the corresponding interface. If DHCP is disabled, this will match the Current gateway
/// </summary>
public uint StaticDefaultGateway { get; set; }
/// <summary>
/// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask
/// </summary>
public uint StaticSubnetMask { get; set; }
/// <summary>
/// Reports the current DomainFeedback on the corresponding interface
/// </summary>
public uint Domain { get; set; }
/// <summary>
/// Reports the current DNS Servers on the corresponding interface
/// </summary>
public uint DnsServer { get; set; }
/// <summary>
/// Reports the MAC Address of the corresponding interface
/// </summary>
public uint MacAddress { get; set; }
/// <summary>
/// Reports the DHCP Status of the corresponding interface
/// </summary>
public uint DhcpStatus { get; set; }
#endregion #endregion
public SystemMonitorJoinMap() public SystemMonitorJoinMap()
@@ -93,6 +155,8 @@ namespace PepperDash.Essentials.Bridges
SnmpAppVersion = 3; SnmpAppVersion = 3;
BACnetAppVersion = 4; BACnetAppVersion = 4;
ControllerVersion = 5; ControllerVersion = 5;
SerialNumber = 6;
Model = 7;
ProgramStartJoin = 10; ProgramStartJoin = 10;
@@ -110,6 +174,22 @@ namespace PepperDash.Essentials.Bridges
ProgramCrestronDatabaseVersion = 3; ProgramCrestronDatabaseVersion = 3;
ProgramEnvironmentVersion = 4; ProgramEnvironmentVersion = 4;
AggregatedProgramInfo = 5; AggregatedProgramInfo = 5;
EthernetStartJoin = 60;
EthernetOffsetJoin = 15;
HostName = 1;
CurrentIpAddress = 2;
CurrentSubnetMask = 3;
CurrentDefaultGateway = 4;
StaticIpAddress = 5;
StaticSubnetMask = 6;
StaticDefaultGateway = 7;
Domain = 8;
DnsServer = 9;
MacAddress = 10;
DhcpStatus = 11;
} }
public override void OffsetJoinNumbers(uint joinStart) public override void OffsetJoinNumbers(uint joinStart)
@@ -126,6 +206,7 @@ namespace PepperDash.Essentials.Bridges
// Sets the initial join value where the iterated program joins will begin // Sets the initial join value where the iterated program joins will begin
ProgramStartJoin = ProgramStartJoin + joinOffset; ProgramStartJoin = ProgramStartJoin + joinOffset;
EthernetStartJoin = EthernetStartJoin + joinOffset;
} }
} }
} }

View File

@@ -31,25 +31,61 @@ namespace PepperDash.Essentials.Bridges
systemMonitorController.SnmpVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.SnmpAppVersion]); systemMonitorController.SnmpVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.SnmpAppVersion]);
systemMonitorController.BaCnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]); systemMonitorController.BaCnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]);
systemMonitorController.ControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.ControllerVersion]); systemMonitorController.ControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.ControllerVersion]);
systemMonitorController.SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumber]);
systemMonitorController.ModelFeedback.LinkInputSig(trilist.StringInput[joinMap.Model]);
// iterate the program status feedback collection and map all the joins // iterate the program status feedback collection and map all the joins
LinkProgramInfoJoins(systemMonitorController, trilist, joinMap);
LinkEthernetInfoJoins(systemMonitorController, trilist, joinMap);
}
private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap)
{
var ethernetSlotJoinStart = joinMap.EthernetStartJoin;
foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection)
{
fb.Value.CurrentIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentIpAddress]);
fb.Value.CurrentSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentSubnetMask]);
fb.Value.CurrentDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentDefaultGateway]);
fb.Value.StaticIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticIpAddress]);
fb.Value.StaticSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticSubnetMask]);
fb.Value.StaticDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticDefaultGateway]);
fb.Value.HostNameFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.HostName]);
fb.Value.MacAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.MacAddress]);
fb.Value.DomainFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.Domain]);
fb.Value.DnsServerFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DnsServer]);
fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus]);
}
}
private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist,
SystemMonitorJoinMap joinMap)
{
var programSlotJoinStart = joinMap.ProgramStartJoin; var programSlotJoinStart = joinMap.ProgramStartJoin;
foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection) foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection)
{ {
var programNumber = p.Value.Program.Number; var programNumber = p.Value.Program.Number;
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart, b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start); trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart,
b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start);
p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart]); p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart]);
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop, b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop); trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop,
b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop);
p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop]); p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop]);
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister, b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register); trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister,
p.Value.ProgramRegisteredFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]); b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register);
p.Value.ProgramRegisteredFeedback.LinkInputSig(
trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]);
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister, b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister); trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister,
p.Value.ProgramUnregisteredFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]); b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister);
p.Value.ProgramUnregisteredFeedback.LinkInputSig(
trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]);
p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName]); p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName]);
p.Value.ProgramCompileTimeFeedback.LinkInputSig( p.Value.ProgramCompileTimeFeedback.LinkInputSig(

View File

@@ -14,12 +14,10 @@ namespace PepperDash.Essentials.Core.Monitoring
/// </summary> /// </summary>
public class SystemMonitorController : Device public class SystemMonitorController : Device
{ {
protected const short LanAdapterIndex = 0;
protected const short CsAdapterIndex = 1;
public event EventHandler<EventArgs> SystemMonitorPropertiesChanged; public event EventHandler<EventArgs> SystemMonitorPropertiesChanged;
public Dictionary<uint, ProgramStatusFeedbacks> ProgramStatusFeedbackCollection; public Dictionary<uint, ProgramStatusFeedbacks> ProgramStatusFeedbackCollection;
public Dictionary<short, EthernetStatusFeedbacks> EthernetStatusFeedbackCollection;
public IntFeedback TimeZoneFeedback { get; protected set; } public IntFeedback TimeZoneFeedback { get; protected set; }
public StringFeedback TimeZoneTextFeedback { get; protected set; } public StringFeedback TimeZoneTextFeedback { get; protected set; }
@@ -30,20 +28,8 @@ namespace PepperDash.Essentials.Core.Monitoring
public StringFeedback ControllerVersionFeedback { get; protected set; } public StringFeedback ControllerVersionFeedback { get; protected set; }
//new feedbacks. Issue #50 //new feedbacks. Issue #50
public StringFeedback HostName { get; protected set; } public StringFeedback SerialNumberFeedback { get; protected set; }
public StringFeedback SerialNumber { get; protected set; } public StringFeedback ModelFeedback { get; set; }
public StringFeedback Model { get; set; }
public StringFeedback LanIpAddress { get; protected set; }
public StringFeedback DefaultGateway { get; protected set; }
public StringFeedback Domain { get; protected set; }
public StringFeedback DnsServer { get; protected set; }
public StringFeedback LanMacAddress { get; protected set; }
public StringFeedback LanSubnetMask { get; protected set; }
public StringFeedback CsIpAddress { get; protected set; }
public StringFeedback CsSubnetMask { get; protected set; }
public BoolFeedback DhcpEnabled { get; protected set; }
public SystemMonitorController(string key) public SystemMonitorController(string key)
@@ -61,6 +47,9 @@ namespace PepperDash.Essentials.Core.Monitoring
BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion); BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion);
ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion); ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion);
SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber);
ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName);
ProgramStatusFeedbackCollection = new Dictionary<uint, ProgramStatusFeedbacks>(); ProgramStatusFeedbackCollection = new Dictionary<uint, ProgramStatusFeedbacks>();
foreach (var prog in SystemMonitor.ProgramCollection) foreach (var prog in SystemMonitor.ProgramCollection)
@@ -69,70 +58,32 @@ namespace PepperDash.Essentials.Core.Monitoring
ProgramStatusFeedbackCollection.Add(prog.Number, program); ProgramStatusFeedbackCollection.Add(prog.Number, program);
} }
CreateControllerFeedbacks(); CreateEthernetStatusFeedbacks();
SystemMonitor.ProgramChange += SystemMonitor_ProgramChange; SystemMonitor.ProgramChange += SystemMonitor_ProgramChange;
SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange; SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange;
CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler;
} }
private void CreateControllerFeedbacks() private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs)
{ {
//assuming 0 = LAN, 1 = CS for devices that have CS if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return;
HostName =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, LanAdapterIndex));
SerialNumber = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber);
Model = new StringFeedback(() => InitialParametersClass.ControllerPromptName);
LanIpAddress =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, LanAdapterIndex));
DefaultGateway =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, LanAdapterIndex));
Domain =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, LanAdapterIndex));
DnsServer =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, LanAdapterIndex));
LanMacAddress =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, LanAdapterIndex));
LanSubnetMask =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPMASK, LanAdapterIndex));
CsIpAddress = foreach (var fb in EthernetStatusFeedbackCollection)
new StringFeedback( {
() => fb.Value.UpdateEthernetStatus();
InitialParametersClass.NumberOfEthernetInterfaces > 1 }
? CrestronEthernetHelper.GetEthernetParameter( }
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, CsAdapterIndex)
: String.Empty);
CsSubnetMask = new StringFeedback(() => InitialParametersClass.NumberOfEthernetInterfaces > 1
? CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, CsAdapterIndex)
: String.Empty);
DhcpEnabled = new BoolFeedback( private void CreateEthernetStatusFeedbacks()
() => {
CrestronEthernetHelper.GetEthernetParameter( EthernetStatusFeedbackCollection = new Dictionary<short, EthernetStatusFeedbacks>();
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, LanAdapterIndex) ==
"Enabled"); for (short i = 0; i < InitialParametersClass.NumberOfEthernetInterfaces; i++)
{
var ethernetInterface = new EthernetStatusFeedbacks(i);
EthernetStatusFeedbackCollection.Add(i, ethernetInterface);
}
} }
/// <summary> /// <summary>
@@ -152,6 +103,8 @@ namespace PepperDash.Essentials.Core.Monitoring
SnmpVersionFeedback.FireUpdate(); SnmpVersionFeedback.FireUpdate();
BaCnetAppVersionFeedback.FireUpdate(); BaCnetAppVersionFeedback.FireUpdate();
ControllerVersionFeedback.FireUpdate(); ControllerVersionFeedback.FireUpdate();
SerialNumberFeedback.FireUpdate();
ModelFeedback.FireUpdate();
OnSystemMonitorPropertiesChanged(); OnSystemMonitorPropertiesChanged();
} }
@@ -226,6 +179,98 @@ namespace PepperDash.Essentials.Core.Monitoring
OnSystemMonitorPropertiesChanged(); OnSystemMonitorPropertiesChanged();
} }
public class EthernetStatusFeedbacks
{
public StringFeedback HostNameFeedback { get; protected set; }
public StringFeedback DnsServerFeedback { get; protected set; }
public StringFeedback DomainFeedback { get; protected set; }
public StringFeedback MacAddressFeedback { get; protected set; }
public StringFeedback DhcpStatusFeedback { get; protected set; }
public StringFeedback CurrentIpAddressFeedback { get; protected set; }
public StringFeedback CurrentSubnetMaskFeedback { get; protected set; }
public StringFeedback CurrentDefaultGatewayFeedback { get; protected set; }
public StringFeedback StaticIpAddressFeedback { get; protected set; }
public StringFeedback StaticSubnetMaskFeedback { get; protected set; }
public StringFeedback StaticDefaultGatewayFeedback { get; protected set; }
public EthernetStatusFeedbacks(short adapterIndex)
{
HostNameFeedback =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex));
CurrentIpAddressFeedback =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex));
CurrentDefaultGatewayFeedback =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex));
CurrentSubnetMaskFeedback =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex));
StaticIpAddressFeedback =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex));
StaticDefaultGatewayFeedback =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex));
StaticSubnetMaskFeedback =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex));
DomainFeedback =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex));
DnsServerFeedback =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex));
MacAddressFeedback =
new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex));
DhcpStatusFeedback = new StringFeedback(
() =>
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex));
}
public void UpdateEthernetStatus()
{
HostNameFeedback.FireUpdate();
CurrentIpAddressFeedback.FireUpdate();
CurrentSubnetMaskFeedback.FireUpdate();
CurrentDefaultGatewayFeedback.FireUpdate();
StaticIpAddressFeedback.FireUpdate();
StaticSubnetMaskFeedback.FireUpdate();
StaticDefaultGatewayFeedback.FireUpdate();
DomainFeedback.FireUpdate();
DnsServerFeedback.FireUpdate();
MacAddressFeedback.FireUpdate();
DhcpStatusFeedback.FireUpdate();
}
}
public class ProgramStatusFeedbacks public class ProgramStatusFeedbacks
{ {