diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nRts/C2nRthsController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nRts/C2nRthsController.cs index 73279368..8416efac 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nRts/C2nRthsController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nRts/C2nRthsController.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.GeneralIO; @@ -13,21 +14,30 @@ namespace PepperDash.Essentials.Core.CrestronIO [Description("Wrapper class for the C2N-RTHS sensor")] public class C2nRthsController : CrestronGenericBridgeableBaseDevice { - private readonly C2nRths _device; + private C2nRths _device; public IntFeedback TemperatureFeedback { get; private set; } public IntFeedback HumidityFeedback { get; private set; } - public C2nRthsController(string key, string name, GenericBase hardware) : base(key, name, hardware) + public C2nRthsController(string key, Func preActivationFunc, + DeviceConfig config) + : base(key, config.Name) { - _device = hardware as C2nRths; - TemperatureFeedback = new IntFeedback(() => _device.TemperatureFeedback.UShortValue); - HumidityFeedback = new IntFeedback(() => _device.HumidityFeedback.UShortValue); + AddPreActivationAction(() => + { + _device = preActivationFunc(config); - if (_device != null) _device.BaseEvent += DeviceOnBaseEvent; + RegisterCrestronGenericBase(_device); + + TemperatureFeedback = new IntFeedback(() => _device.TemperatureFeedback.UShortValue); + HumidityFeedback = new IntFeedback(() => _device.HumidityFeedback.UShortValue); + + if (_device != null) _device.BaseEvent += DeviceOnBaseEvent; + }); } + private void DeviceOnBaseEvent(GenericBase device, BaseEventArgs args) { switch (args.EventId) @@ -76,24 +86,63 @@ namespace PepperDash.Essentials.Core.CrestronIO HumidityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Humidity.JoinNumber]); trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name; - } - } - public class C2nRthsControllerFactory : EssentialsDeviceFactory - { - public C2nRthsControllerFactory() - { - TypeNames = new List() { "c2nrths" }; + trilist.OnlineStatusChange += (d, args) => + { + if (!args.DeviceOnLine) return; + + UpdateFeedbacksWhenOnline(); + + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name; + }; } - public override EssentialsDevice BuildDevice(DeviceConfig dc) + private void UpdateFeedbacksWhenOnline() { - Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device"); + IsOnline.FireUpdate(); + TemperatureFeedback.FireUpdate(); + HumidityFeedback.FireUpdate(); + } + #region PreActivation + + private static C2nRths GetC2nRthsDevice(DeviceConfig dc) + { var control = CommFactory.GetControlPropertiesConfig(dc); var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; - return new C2nRthsController(dc.Key, dc.Name, new C2nRths(cresnetId, Global.ControlSystem)); + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new C2nRths", parentKey); + return new C2nRths(cresnetId, Global.ControlSystem); + } + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as ICresnetBridge; + + if (cresnetBridge != null) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new C2nRths", parentKey); + return new C2nRths(cresnetId, cresnetBridge.Branches[branchId]); + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; + } + #endregion + + public class C2nRthsControllerFactory : EssentialsDeviceFactory + { + public C2nRthsControllerFactory() + { + TypeNames = new List() { "c2nrths" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device"); + + return new C2nRthsController(dc.Key, GetC2nRthsDevice, dc); + } } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/StatusSign/StatusSignController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/StatusSign/StatusSignController.cs index 1bd22ebe..b269745e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/StatusSign/StatusSignController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/StatusSign/StatusSignController.cs @@ -13,7 +13,7 @@ namespace PepperDash.Essentials.Core.CrestronIO [Description("Wrapper class for the Crestron StatusSign device")] public class StatusSignController : CrestronGenericBridgeableBaseDevice { - private readonly StatusSign _device; + private StatusSign _device; public BoolFeedback RedLedEnabledFeedback { get; private set; } public BoolFeedback GreenLedEnabledFeedback { get; private set; } @@ -23,34 +23,40 @@ namespace PepperDash.Essentials.Core.CrestronIO public IntFeedback GreenLedBrightnessFeedback { get; private set; } public IntFeedback BlueLedBrightnessFeedback { get; private set; } - public StatusSignController(string key, string name, GenericBase hardware) : base(key, name, hardware) + public StatusSignController(string key, Func preActivationFunc, DeviceConfig config) : base(key, config.Name) { - _device = hardware as StatusSign; + AddPreActivationAction(() => + { + _device = preActivationFunc(config); - RedLedEnabledFeedback = + RegisterCrestronGenericBase(_device); + + RedLedEnabledFeedback = new BoolFeedback( () => - _device.Leds[(uint) StatusSign.Led.eLedColor.Red] - .ControlFeedback.BoolValue); - GreenLedEnabledFeedback = - new BoolFeedback( - () => - _device.Leds[(uint) StatusSign.Led.eLedColor.Green] - .ControlFeedback.BoolValue); - BlueLedEnabledFeedback = - new BoolFeedback( - () => - _device.Leds[(uint) StatusSign.Led.eLedColor.Blue] + _device.Leds[(uint)StatusSign.Led.eLedColor.Red] .ControlFeedback.BoolValue); + GreenLedEnabledFeedback = + new BoolFeedback( + () => + _device.Leds[(uint)StatusSign.Led.eLedColor.Green] + .ControlFeedback.BoolValue); + BlueLedEnabledFeedback = + new BoolFeedback( + () => + _device.Leds[(uint)StatusSign.Led.eLedColor.Blue] + .ControlFeedback.BoolValue); - RedLedBrightnessFeedback = - new IntFeedback(() => (int) _device.Leds[(uint) StatusSign.Led.eLedColor.Red].BrightnessFeedback); - GreenLedBrightnessFeedback = - new IntFeedback(() => (int) _device.Leds[(uint) StatusSign.Led.eLedColor.Green].BrightnessFeedback); - BlueLedBrightnessFeedback = - new IntFeedback(() => (int) _device.Leds[(uint) StatusSign.Led.eLedColor.Blue].BrightnessFeedback); + RedLedBrightnessFeedback = + new IntFeedback(() => (int)_device.Leds[(uint)StatusSign.Led.eLedColor.Red].BrightnessFeedback); + GreenLedBrightnessFeedback = + new IntFeedback(() => (int)_device.Leds[(uint)StatusSign.Led.eLedColor.Green].BrightnessFeedback); + BlueLedBrightnessFeedback = + new IntFeedback(() => (int)_device.Leds[(uint)StatusSign.Led.eLedColor.Blue].BrightnessFeedback); - if (_device != null) _device.BaseEvent += _device_BaseEvent; + if (_device != null) _device.BaseEvent += _device_BaseEvent; + + }); } void _device_BaseEvent(GenericBase device, BaseEventArgs args) @@ -167,23 +173,51 @@ namespace PepperDash.Essentials.Core.CrestronIO device.SetColor(redBrightness, greenBrightness, blueBrightness); } - } - public class StatusSignControllerFactory : EssentialsDeviceFactory - { - public StatusSignControllerFactory() + #region PreActivation + + private static StatusSign GetStatusSignDevice(DeviceConfig dc) { - TypeNames = new List() { "statussign" }; - } - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new StatusSign Device"); - var control = CommFactory.GetControlPropertiesConfig(dc); var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; - return new StatusSignController(dc.Key, dc.Name, new StatusSign(cresnetId, Global.ControlSystem)); + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new StatusSign", parentKey); + return new StatusSign(cresnetId, Global.ControlSystem); + } + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as ICresnetBridge; + + if (cresnetBridge != null) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new StatusSign", parentKey); + return new StatusSign(cresnetId, cresnetBridge.Branches[branchId]); + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; + } + #endregion + + public class StatusSignControllerFactory : EssentialsDeviceFactory + { + public StatusSignControllerFactory() + { + TypeNames = new List() { "statussign" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new StatusSign Device"); + + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + + return new StatusSignController(dc.Key, GetStatusSignDevice, dc); + } } } + + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs index 7866075f..9db81122 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs @@ -1,7 +1,9 @@ -using System.Linq; +using System; +using System.Linq; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; +using PepperDash.Core.JsonStandardObjects; using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core @@ -11,7 +13,7 @@ namespace PepperDash.Essentials.Core /// public abstract class CrestronGenericBaseDevice : EssentialsDevice, IOnline, IHasFeedback, ICommunicationMonitor, IUsageTracking { - public virtual GenericBase Hardware { get; protected set; } + protected GenericBase Hardware; /// /// Returns a list containing the Outputs that we want to expose. @@ -42,6 +44,24 @@ namespace PepperDash.Essentials.Core CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000); } + protected CrestronGenericBaseDevice(string key, string name) + : base(key, name) + { + Feedbacks = new FeedbackCollection(); + + } + + protected void RegisterCrestronGenericBase(GenericBase hardware) + { + Hardware = hardware; + IsOnline = new BoolFeedback("IsOnlineFeedback", () => Hardware.IsOnline); + IsRegistered = new BoolFeedback("IsRegistered", () => Hardware.Registered); + IpConnectionsText = new StringFeedback("IpConnectionsText", () => Hardware.ConnectedIpList != null ? string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()) : string.Empty); + AddToFeedbackList(IsOnline, IpConnectionsText); + + CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000); + } + /// /// Make sure that overriding classes call this! /// Registers the Crestron device, connects up to the base events, starts communication monitor @@ -135,6 +155,11 @@ namespace PepperDash.Essentials.Core { } + protected CrestronGenericBridgeableBaseDevice(string key, string name) + : base(key, name) + { + } + public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs new file mode 100644 index 00000000..89c0b7b3 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash_Essentials_Core +{ + public class IsReadyEventArgs : EventArgs + { + public bool IsReady { get; set; } + + public IsReadyEventArgs(bool data) + { + IsReady = data; + } + } + + public interface IHasReady + { + event EventHandler IsReadyEvent; + bool IsReady { get; } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Gateways/CenRfgwController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Gateways/CenRfgwController.cs index 1fd7da6d..fb7968d9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Gateways/CenRfgwController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Gateways/CenRfgwController.cs @@ -6,134 +6,192 @@ using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.Gateways; using Newtonsoft.Json; +using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; +using PepperDash_Essentials_Core; -namespace PepperDash.Essentials.Core +namespace PepperDash.Essentials.Core { - [Description("Wrapper class for Crestron Infinet-EX Gateways")] - public class CenRfgwController : CrestronGenericBaseDevice - { - private GatewayBase _Gateway; - public GatewayBase GateWay { get { return _Gateway; } } - - /// - /// Constructor for the on-board gateway - /// - /// - /// - public CenRfgwController(string key, string name, GatewayBase gateway) : - base(key, name, gateway) - { - _Gateway = gateway; - } - - public static CenRfgwController GetNewExGatewayController(string key, string name, ushort ipId, ushort cresnetId, string gatewayType) - { - eExGatewayType type = (eExGatewayType)Enum.Parse(typeof(eExGatewayType), gatewayType, true); - try - { - var cs = Global.ControlSystem; - - GatewayBase gw = null; - switch (type) - { - case eExGatewayType.Ethernet: - gw = new CenRfgwEx(ipId, cs); - break; - case eExGatewayType.EthernetShared: - gw = new CenRfgwExEthernetSharable(ipId, cs); - break; - case eExGatewayType.Cresnet: - gw = new CenRfgwExCresnet(cresnetId, cs); - break; - } - return new CenRfgwController(key, name, gw); - } - catch (Exception) - { - Debug.Console(0, "ERROR: Cannot create EX Gateway, id {0}, type {1}", type == eExGatewayType.Cresnet ? cresnetId : ipId, gatewayType); - return null; - } - } - public static CenRfgwController GetNewErGatewayController(string key, string name, ushort ipId, ushort cresnetId, string gatewayType) - { - eExGatewayType type = (eExGatewayType)Enum.Parse(typeof(eExGatewayType), gatewayType, true); - try - { - var cs = Global.ControlSystem; - - GatewayBase gw = null; - switch (type) - { - case eExGatewayType.Ethernet: - gw = new CenErfgwPoe(ipId, cs); - break; - case eExGatewayType.EthernetShared: - gw = new CenErfgwPoeEthernetSharable(ipId, cs); - break; - case eExGatewayType.Cresnet: - gw = new CenErfgwPoeCresnet(cresnetId, cs); - break; - } - return new CenRfgwController(key, name, gw); - } - catch (Exception) - { - Debug.Console(0, "ERROR: Cannot create ER Gateway, id {0}, type {1}", type== eExGatewayType.Cresnet ? cresnetId : ipId, gatewayType); - return null; - } - } - - } - - - - public enum eExGatewayType - { - Ethernet, EthernetShared, Cresnet - } + [Description("Wrapper class for Crestron Infinet-EX Gateways")] + public class CenRfgwController : CrestronGenericBaseDevice, IHasReady + { + public event EventHandler IsReadyEvent; + public bool IsReady { get; private set; } - #region Factory - public class CenRfgwControllerFactory : EssentialsDeviceFactory - { - public CenRfgwControllerFactory() - { - TypeNames = new List() { "cenrfgwex", "cenerfgwpoe" }; - } + private GatewayBase _gateway; - public override EssentialsDevice BuildDevice(DeviceConfig dc) + public GatewayBase GateWay { - - Debug.Console(1, "Factory Attempting to create new CEN-GWEXER Device"); - - var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); - - var type = dc.Type.ToLower(); - var control = props.Control; - var ipid = control.IpIdInt; - var cresnetId = control.CresnetIdInt; - var gatewayType = props.GatewayType; - - switch (type) - { - case ("cenrfgwex"): - return CenRfgwController.GetNewExGatewayController(dc.Key, dc.Name, - (ushort)ipid, (ushort)cresnetId, gatewayType); - case ("cenerfgwpoe"): - return CenRfgwController.GetNewErGatewayController(dc.Key, dc.Name, - (ushort)ipid, (ushort)cresnetId, gatewayType); - default: - return null; - } + get { return _gateway; } } + + /// + /// Constructor for the on-board gateway + /// + /// + /// + /// + public CenRfgwController(string key, string name, GatewayBase gateway) : + base(key, name, gateway) + { + _gateway = gateway; + IsReady = true; + FireIsReadyEvent(IsReady); + } + + public CenRfgwController(string key, Func preActivationFunc, DeviceConfig config) : + base(key, config.Name) + { + IsReady = false; + FireIsReadyEvent(IsReady); + AddPreActivationAction(() => + { + _gateway = preActivationFunc(config); + + IsReady = true; + RegisterCrestronGenericBase(_gateway); + FireIsReadyEvent(IsReady); + + }); + } + + public static GatewayBase GetNewIpRfGateway(DeviceConfig dc) + { + var control = CommFactory.GetControlPropertiesConfig(dc); + var type = dc.Type; + var ipId = control.IpIdInt; + + if (type.Equals("cenrfgwex", StringComparison.InvariantCultureIgnoreCase)) + { + return new CenRfgwEx(ipId, Global.ControlSystem); + } + if (type.Equals("cenerfgwpoe", StringComparison.InvariantCultureIgnoreCase)) + { + return new CenErfgwPoe(ipId, Global.ControlSystem); + } + return null; + } + + private void FireIsReadyEvent(bool data) + { + var handler = IsReadyEvent; + if (handler == null) return; + + handler(this, new IsReadyEventArgs(data)); + + } + + public static GatewayBase GetNewSharedIpRfGateway(DeviceConfig dc) + { + var control = CommFactory.GetControlPropertiesConfig(dc); + var ipId = control.IpIdInt; + + if (dc.Type.Equals("cenrfgwex", StringComparison.InvariantCultureIgnoreCase)) + { + return new CenRfgwExEthernetSharable(ipId, Global.ControlSystem); + } + if (dc.Type.Equals("cenerfgwpoe", StringComparison.InvariantCultureIgnoreCase)) + { + return new CenErfgwPoeEthernetSharable(ipId, Global.ControlSystem); + } + return null; + } + + public static GatewayBase GetCenRfgwCresnetController(DeviceConfig dc) + { + var control = CommFactory.GetControlPropertiesConfig(dc); + var type = dc.Type; + var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; + + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new CenRfgw", parentKey); + if (type.Equals("cenerfgwpoe", StringComparison.InvariantCultureIgnoreCase)) + { + return new CenErfgwPoeCresnet(cresnetId, Global.ControlSystem); + } + if (type.Equals("cenrfgwex", StringComparison.InvariantCultureIgnoreCase)) + { + return new CenRfgwExCresnet(cresnetId, Global.ControlSystem); + } + } + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as ICresnetBridge; + + if (cresnetBridge != null) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new CenRfgw", parentKey); + + if (type.Equals("cenerfgwpoe", StringComparison.InvariantCultureIgnoreCase)) + { + return new CenErfgwPoeCresnet(cresnetId, cresnetBridge.Branches[branchId]); + } + if (type.Equals("cenrfgwex", StringComparison.InvariantCultureIgnoreCase)) + { + return new CenRfgwExCresnet(cresnetId, cresnetBridge.Branches[branchId]); + } + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; + } + + + + + + + + public enum EExGatewayType + { + Ethernet, + EthernetShared, + Cresnet + } + + + #region Factory + + public class CenRfgwControllerFactory : EssentialsDeviceFactory + { + public CenRfgwControllerFactory() + { + TypeNames = new List {"cenrfgwex", "cenerfgwpoe"}; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + + Debug.Console(1, "Factory Attempting to create new CEN-GWEXER Device"); + + var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); + + EExGatewayType gatewayType = + (EExGatewayType) Enum.Parse(typeof (EExGatewayType), props.GatewayType, true); + + switch (gatewayType) + { + case (EExGatewayType.Ethernet): + return new CenRfgwController(dc.Key, dc.Name, GetNewIpRfGateway(dc)); + case (EExGatewayType.EthernetShared): + return new CenRfgwController(dc.Key, dc.Name, GetNewSharedIpRfGateway(dc)); + case (EExGatewayType.Cresnet): + return new CenRfgwController(dc.Key, GetCenRfgwCresnetController, dc); + } + return null; + } + } + + #endregion } - #endregion + + +} -} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/PartitionSensor/GlsPartitionSensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs similarity index 62% rename from essentials-framework/Essentials Devices Common/Essentials Devices Common/PartitionSensor/GlsPartitionSensorController.cs rename to essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs index 29847144..44dfbb4b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/PartitionSensor/GlsPartitionSensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs @@ -7,12 +7,28 @@ using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash_Essentials_Core.Bridges.JoinMaps; -namespace PepperDash.Essentials.Devices.Common.PartitionSensor +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.Gateways; +using Newtonsoft.Json; +using Crestron.SimplSharpPro.DeviceSupport; + + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash_Essentials_Core; + +namespace PepperDash.Essentials.Core { [Description("Wrapper class for GLS Cresnet Partition Sensor")] public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice { - private readonly GlsPartCn _partitionSensor; + private GlsPartCn _partitionSensor; public StringFeedback NameFeedback { get; private set; } public BoolFeedback EnableFeedback { get; private set; } @@ -25,27 +41,26 @@ namespace PepperDash.Essentials.Devices.Common.PartitionSensor public bool TestPartitionSensedFeedback { get; private set; } public int TestSensitivityFeedback { get; private set; } - /// - /// Constructor - /// - /// - /// - /// - public GlsPartitionSensorController(string key, string name, GlsPartCn hardware) - : base(key, name, hardware) + + public GlsPartitionSensorController(string key, Func preActivationFunc, DeviceConfig config) + : base(key, config.Name) { - _partitionSensor = hardware; + AddPreActivationAction(() => + { + _partitionSensor = preActivationFunc(config); - NameFeedback = new StringFeedback(() => Name); - EnableFeedback = new BoolFeedback(() => _partitionSensor.EnableFeedback.BoolValue); - PartitionSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue); - PartitionNotSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionNotSensedFeedback.BoolValue); - SensitivityFeedback = new IntFeedback(() => _partitionSensor.SensitivityFeedback.UShortValue); + RegisterCrestronGenericBase(_partitionSensor); - if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent; + NameFeedback = new StringFeedback(() => Name); + EnableFeedback = new BoolFeedback(() => _partitionSensor.EnableFeedback.BoolValue); + PartitionSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue); + PartitionNotSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionNotSensedFeedback.BoolValue); + SensitivityFeedback = new IntFeedback(() => _partitionSensor.SensitivityFeedback.UShortValue); + + if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent; + }); } - private void PartitionSensor_BaseEvent(GenericBase device, BaseEventArgs args) { Debug.Console(2, this, "EventId: {0}, Index: {1}", args.EventId, args.Index); @@ -218,5 +233,48 @@ namespace PepperDash.Essentials.Devices.Common.PartitionSensor PartitionNotSensedFeedback.FireUpdate(); SensitivityFeedback.FireUpdate(); } + + #region PreActivation + + private static GlsPartCn GetGlsPartCnDevice(DeviceConfig dc) + { + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; + + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsPartCn", parentKey); + return new GlsPartCn(cresnetId, Global.ControlSystem); + } + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as ICresnetBridge; + + if (cresnetBridge != null) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsPartCn", parentKey); + return new GlsPartCn(cresnetId, cresnetBridge.Branches[branchId]); + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; + } + #endregion + + + public class GlsPartitionSensorControllerFactory : EssentialsDeviceFactory + { + public GlsPartitionSensorControllerFactory() + { + TypeNames = new List() { "glspartcn" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device"); + + return new GlsPartitionSensorController(dc.Key, GetGlsPartCnDevice, dc); + } + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index f4eeabe5..98343f35 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -193,6 +193,7 @@ + @@ -214,6 +215,7 @@ + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Remotes/Hrxx0WirelessRemoteController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Remotes/Hrxx0WirelessRemoteController.cs index 746f449f..311df7f1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Remotes/Hrxx0WirelessRemoteController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Remotes/Hrxx0WirelessRemoteController.cs @@ -21,30 +21,70 @@ namespace PepperDash.Essentials.Core [Description("Wrapper class for all HR-Series remotes")] public class Hrxx0WirelessRemoteController : EssentialsBridgeableDevice, IHasFeedback { + private CenRfgwController _gateway; + private Hr1x0WirelessRemoteBase _remote; public FeedbackCollection Feedbacks { get; set; } public CrestronCollection - void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) - { - var output = args.Number; - - switch (args.EventId) - { - case DMOutputEventIds.VolumeEventId: - { - if (VolumeControls.ContainsKey(output)) - { - VolumeControls[args.Number].VolumeEventFromChassis(); - } - - break; - } - case DMOutputEventIds.EndpointOnlineEventId: - { - Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. State: {1}", args.Number, - Chassis.Outputs[output].EndpointOnlineFeedback); - OutputEndpointOnlineFeedbacks[output].FireUpdate(); - break; - } - case DMOutputEventIds.OnlineFeedbackEventId: - { - Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}", args.Number, - Chassis.Outputs[output].EndpointOnlineFeedback); - OutputEndpointOnlineFeedbacks[output].FireUpdate(); - break; - } - case DMOutputEventIds.VideoOutEventId: - { - if (Chassis.Outputs[output].VideoOutFeedback != null) - Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].VideoOutFeedback.Number, output); - - if (VideoOutputFeedbacks.ContainsKey(output)) - VideoOutputFeedbacks[output].FireUpdate(); - - if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) - OutputVideoRouteNameFeedbacks[output].FireUpdate(); - - break; - } - case DMOutputEventIds.AudioOutEventId: - { - if (Chassis.Outputs[output].AudioOutFeedback != null) - Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].AudioOutFeedback.Number, output); - - if (AudioOutputFeedbacks.ContainsKey(output)) - AudioOutputFeedbacks[output].FireUpdate(); - - if (OutputAudioRouteNameFeedbacks.ContainsKey(output)) - OutputAudioRouteNameFeedbacks[output].FireUpdate(); - - break; - } - case DMOutputEventIds.OutputNameEventId: - { - Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output); - OutputNameFeedbacks[output].FireUpdate(); - break; - } - case DMOutputEventIds.UsbRoutedToEventId: - { - Debug.Console(2, this, "DM Output {0} UsbRoutedToEventId", args.Number); - UsbOutputRoutedToFeebacks[args.Number].FireUpdate(); - break; - } - case DMOutputEventIds.DisabledByHdcpEventId: - { - Debug.Console(2, this, "DM Output {0} DisabledByHdcpEventId", args.Number); - OutputDisabledByHdcpFeedbacks[args.Number].FireUpdate(); - break; - } - default: - { - Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", args.Number, args.EventId); - break; - } - } - } - - /// - /// - /// - /// - void StartOffTimer(PortNumberType pnt) - { - if (RouteOffTimers.ContainsKey(pnt)) - return; - RouteOffTimers[pnt] = new CTimer(o => { ExecuteSwitch(0, pnt.Number, pnt.Type); }, RouteOffTime); - } - - // Send out sigs when coming online - void IsOnline_OutputChange(object sender, EventArgs e) - { - if (IsOnline.BoolValue) - { - (Chassis as DmMDMnxn).EnableAudioBreakaway.BoolValue = true; - (Chassis as DmMDMnxn).EnableUSBBreakaway.BoolValue = true; - - - EnableAudioBreakawayFeedback.FireUpdate(); - EnableUsbBreakawayFeedback.FireUpdate(); - - if (InputNames != null) - foreach (var kvp in InputNames) - Chassis.Inputs[kvp.Key].Name.StringValue = kvp.Value; - if (OutputNames != null) - foreach (var kvp in OutputNames) - Chassis.Outputs[kvp.Key].Name.StringValue = kvp.Value; - } - } - - #region IRouting Members - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) - { - Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType); - - var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail - var output = Convert.ToUInt32(outputSelector); - - var chassisSize = (uint) Chassis.NumberOfInputs; //need this to determine USB routing values 8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 - //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 - //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 - - // Check to see if there's an off timer waiting on this and if so, cancel - var key = new PortNumberType(output, sigType); - if (input == 0) - { - StartOffTimer(key); - } - else - { - if (RouteOffTimers.ContainsKey(key)) - { - Debug.Console(2, this, "{0} cancelling route off due to new source", output); - RouteOffTimers[key].Stop(); - RouteOffTimers.Remove(key); - } - } - - var inCard = input == 0 ? null : Chassis.Inputs[input]; - var outCard = input == 0 ? null : Chassis.Outputs[output]; - - // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES - if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) - { - Chassis.VideoEnter.BoolValue = true; - Chassis.Outputs[output].VideoOut = inCard; - } - - if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio) - { - (Chassis as DmMDMnxn).AudioEnter.BoolValue = true; - Chassis.Outputs[output].AudioOut = inCard; - } - - if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) - { - //using base here because USB can be routed between 2 output cards or 2 input cards - DMInputOutputBase dmCard; - - Debug.Console(2, this, "Executing USB Output switch.\r\n in:{0} output: {1}", input, output); - - if (input > chassisSize) - { - //wanting to route an output to an output. Subtract chassis size and get output, unless it's 8x8 - //need this to determine USB routing values - //8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 - //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 - //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 - uint outputIndex; - - if (chassisSize == 8) - { - outputIndex = input - 16; - } - else - { - outputIndex = input - chassisSize; - } - dmCard = Chassis.Outputs[outputIndex]; - } - else - { - dmCard = inCard; - } - Chassis.USBEnter.BoolValue = true; - if (Chassis.Outputs[output] != null) - { - Debug.Console(2, this, "Routing USB for input {0} to {1}", Chassis.Outputs[input], dmCard); - Chassis.Outputs[output].USBRoutedTo = dmCard; - } - } - - if ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) - { - //using base here because USB can be routed between 2 output cards or 2 input cards - DMInputOutputBase dmCard; - - Debug.Console(2, this, "Executing USB Input switch.\r\n in:{0} output: {1}", input, output); - - if (output > chassisSize) - { - //wanting to route an input to an output. Subtract chassis size and get output, unless it's 8x8 - //need this to determine USB routing values - //8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 - //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 - //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 - uint outputIndex; - - if (chassisSize == 8) - { - outputIndex = input - 16; - } - else - { - outputIndex = input - chassisSize; - } - dmCard = Chassis.Outputs[outputIndex]; - } - else - { - dmCard = Chassis.Inputs[input]; - } - - - - Chassis.USBEnter.BoolValue = true; - - if (Chassis.Inputs[output] == null) - { - return; - } - Debug.Console(2, this, "Routing USB for input {0} to {1}", Chassis.Inputs[output], dmCard); - Chassis.Inputs[output].USBRoutedTo = dmCard; - } - } - #endregion - - #region IRoutingNumeric Members - - public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) - { - ExecuteSwitch(inputSelector, outputSelector, sigType); - } - - #endregion - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = new DmChassisControllerJoinMap(joinStart); - - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - else - { - Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } - - Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - - var chassis = Chassis as DmMDMnxn; - - IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); - - trilist.SetUShortSigAction(joinMap.SystemId.JoinNumber, o => - { - if (chassis != null) - chassis.SystemId.UShortValue = o; - }); - - trilist.SetSigTrueAction(joinMap.SystemId.JoinNumber, () => - { - if (chassis != null) chassis.ApplySystemId(); - }); - - SystemIdFeebdack.LinkInputSig(trilist.UShortInput[joinMap.SystemId.JoinNumber]); - SystemIdBusyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SystemId.JoinNumber]); - - EnableAudioBreakawayFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAudioBreakaway.JoinNumber]); - EnableUsbBreakawayFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsbBreakaway.JoinNumber]); - - trilist.OnlineStatusChange += (o, a) => - { - if (!a.DeviceOnLine) return; - - EnableAudioBreakawayFeedback.FireUpdate(); - EnableUsbBreakawayFeedback.FireUpdate(); - SystemIdBusyFeedback.FireUpdate(); - SystemIdFeebdack.FireUpdate(); - }; - - // Link up outputs - for (uint i = 1; i <= Chassis.NumberOfOutputs; i++) - { - var ioSlot = i; - var ioSlotJoin = ioSlot - 1; - - // Control - trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)); - trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)); - trilist.SetUShortSigAction(joinMap.OutputUsb.JoinNumber + ioSlotJoin, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbOutput)); - trilist.SetUShortSigAction(joinMap.InputUsb.JoinNumber + ioSlotJoin, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbInput)); - - if (TxDictionary.ContainsKey(ioSlot)) - { - Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); - var txKey = TxDictionary[ioSlot]; - var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase; - - var advancedTxDevice = basicTxDevice as DmTxControllerBase; - - if (Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps - || Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps - || Chassis is DmMd32x32Cpu3 || Chassis is DmMd32x32Cpu3rps) - { - InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); - } - else - { - if (advancedTxDevice != null) - { - advancedTxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); - Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot); - } - else if (InputEndpointOnlineFeedbacks[ioSlot] != null) - { - Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot); - InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); - } - } - - if (basicTxDevice != null && advancedTxDevice == null) - trilist.BooleanInput[joinMap.TxAdvancedIsPresent.JoinNumber + ioSlotJoin].BoolValue = true; - - if (advancedTxDevice != null) - { - advancedTxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); - } - else if (advancedTxDevice == null || basicTxDevice != null) - { - Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot); - VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); - - var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; - if (inputPort != null) - { - Debug.Console(1, "Port value for input card {0} is set", ioSlot); - var port = inputPort.Port; - - if (port != null) - { - if (port is HdmiInputWithCEC) - { - Debug.Console(1, "Port is HdmiInputWithCec"); - - var hdmiInPortWCec = port as HdmiInputWithCEC; - - if (hdmiInPortWCec.HdcpSupportedLevel != eHdcpSupportedLevel.Unknown) - { - SetHdcpStateAction(true, hdmiInPortWCec, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); - } - - InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); - - if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) - trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = (ushort)InputCardHdcpCapabilityTypes[ioSlot]; - else - trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; - } - } - } - else - { - inputPort = InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)]; - - if (inputPort != null) - { - var port = inputPort.Port; - - if (port is DMInputPortWithCec) - { - Debug.Console(1, "Port is DMInputPortWithCec"); - - var dmInPortWCec = port as DMInputPortWithCec; - - if (dmInPortWCec != null) - { - SetHdcpStateAction(PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], dmInPortWCec, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); - } - - InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); - - if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) - trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = (ushort)InputCardHdcpCapabilityTypes[ioSlot]; - else - trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; - } - } - } - } - } - else - { - VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); - - var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; - if (inputPort != null) - { - var hdmiPort = inputPort.Port as EndpointHdmiInput; - - if (hdmiPort != null) - { - SetHdcpStateAction(true, hdmiPort, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); - InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); - } - } - } - - if (RxDictionary.ContainsKey(ioSlot)) - { - Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot); - var rxKey = RxDictionary[ioSlot]; - var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase; - var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase; - if (Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps - || Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps - || Chassis is DmMd32x32Cpu3 || Chassis is DmMd32x32Cpu3rps || hdBaseTDevice != null) - { - OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]); - } - else if (rxDevice != null) - { - rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]); - } - } - - // Feedback - VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo.JoinNumber + ioSlotJoin]); - AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + ioSlotJoin]); - UsbOutputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputUsb.JoinNumber + ioSlotJoin]); - UsbInputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.InputUsb.JoinNumber + ioSlotJoin]); - - OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]); - InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]); - OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + ioSlotJoin]); - OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames.JoinNumber + ioSlotJoin]); - - OutputDisabledByHdcpFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputDisabledByHdcp.JoinNumber + ioSlotJoin]); - } - } - - private void SetHdcpStateAction(bool hdcpTypeSimple, HdmiInputWithCEC port, uint join, BasicTriList trilist) - { - if (hdcpTypeSimple) - { - trilist.SetUShortSigAction(join, - s => - { - if (s == 0) - { - port.HdcpSupportOff(); - } - else if (s > 0) - { - port.HdcpSupportOn(); - } - }); - } - else - { - trilist.SetUShortSigAction(join, - u => - { - port.HdcpReceiveCapability = (eHdcpCapabilityType)u; - }); - } - } - - private void SetHdcpStateAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist) - { - if (hdcpTypeSimple) - { - trilist.SetUShortSigAction(join, - s => - { - if (s == 0) - { - port.HdcpSupportOff(); - } - else if (s > 0) - { - port.HdcpSupportOn(); - } - }); - } - else - { - trilist.SetUShortSigAction(join, - u => - { - port.HdcpCapability = (eHdcpCapabilityType)u; - }); - } - } - - private void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist) - { - if (!supportsHdcp2) - { - trilist.SetUShortSigAction(join, - s => - { - if (s == 0) - { - port.HdcpSupportOff(); - } - else if (s > 0) - { - port.HdcpSupportOn(); - } - }); - } - else - { - trilist.SetUShortSigAction(join, - u => - { - port.HdcpReceiveCapability = (eHdcpCapabilityType)u; - }); - } - } - } - - public struct PortNumberType - { - public uint Number { get; private set; } - public eRoutingSignalType Type { get; private set; } - - public PortNumberType(uint number, eRoutingSignalType type) - : this() - { - Number = number; - Type = type; - } - } - - public class DmChassisControllerFactory : EssentialsDeviceFactory - { - public DmChassisControllerFactory() - { - TypeNames = new List() { "dmmd8x8", "dmmd8x8rps", "dmmd8x8cpu3", "dmmd8x8cpu3rps", - "dmmd16x16", "dmmd16x16rps", "dmmd16x16cpu3", "dmmd16x16cpu3rps", - "dmmd32x32", "dmmd32x32rps", "dmmd32x32cpu3", "dmmd32x32cpu3rps", - "dmmd64x64", "dmmd128x128" }; - } - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - var type = dc.Type.ToLower(); - - Debug.Console(1, "Factory Attempting to create new DmChassisController Device"); - - if (type.StartsWith("dmmd8x") || type.StartsWith("dmmd16x") || type.StartsWith("dmmd32x")) - { - - var props = JsonConvert.DeserializeObject - (dc.Properties.ToString()); - return PepperDash.Essentials.DM.DmChassisController. - GetDmChassisController(dc.Key, dc.Name, type, props); - } - else if (type.StartsWith("dmmd128x") || type.StartsWith("dmmd64x")) - { - var props = JsonConvert.DeserializeObject - (dc.Properties.ToString()); - return PepperDash.Essentials.DM.DmBladeChassisController. - GetDmChassisController(dc.Key, dc.Name, type, props); - } - - return null; - } - } - -} - + +using System; +using System.Collections.Generic; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Cards; +using Crestron.SimplSharpPro.DM.Endpoints; +using Newtonsoft.Json; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.DM.Config; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.DM +{ + /// + /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions + /// + /// + [Description("Wrapper class for all DM-MD chassis variants from 8x8 to 32x32")] + public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumeric + { + public DMChassisPropertiesConfig PropertiesConfig { get; set; } + + public Switch Chassis { get; private set; } + + // Feedbacks for EssentialDM + public Dictionary VideoOutputFeedbacks { get; private set; } + public Dictionary AudioOutputFeedbacks { get; private set; } + public Dictionary VideoInputSyncFeedbacks { get; private set; } + public Dictionary InputEndpointOnlineFeedbacks { get; private set; } + public Dictionary OutputEndpointOnlineFeedbacks { get; private set; } + public Dictionary InputNameFeedbacks { get; private set; } + public Dictionary OutputNameFeedbacks { get; private set; } + public Dictionary OutputVideoRouteNameFeedbacks { get; private set; } + public Dictionary OutputAudioRouteNameFeedbacks { get; private set; } + public Dictionary UsbOutputRoutedToFeebacks { get; private set; } + public Dictionary UsbInputRoutedToFeebacks { get; private set; } + public Dictionary OutputDisabledByHdcpFeedbacks { get; private set; } + + public IntFeedback SystemIdFeebdack { get; private set; } + public BoolFeedback SystemIdBusyFeedback { get; private set; } + public BoolFeedback EnableAudioBreakawayFeedback { get; private set; } + public BoolFeedback EnableUsbBreakawayFeedback { get; private set; } + + public Dictionary InputCardHdcpCapabilityFeedbacks { get; private set; } + + public Dictionary InputCardHdcpCapabilityTypes { get; private set; } + + // Need a couple Lists of generic Backplane ports + public RoutingPortCollection InputPorts { get; private set; } + public RoutingPortCollection OutputPorts { get; private set; } + + public Dictionary TxDictionary { get; set; } + public Dictionary RxDictionary { get; set; } + + //public Dictionary InputCards { get; private set; } + //public Dictionary OutputCards { get; private set; } + + public Dictionary InputNames { get; set; } + public Dictionary OutputNames { get; set; } + public Dictionary VolumeControls { get; private set; } + + public const int RouteOffTime = 500; + Dictionary RouteOffTimers = new Dictionary(); + + /// + /// Text that represents when an output has no source routed to it + /// + public string NoRouteText = ""; + + /// + /// Factory method to create a new chassis controller from config data. Limited to 8x8 right now + /// + public static DmChassisController GetDmChassisController(string key, string name, + string type, DMChassisPropertiesConfig properties) + { + try + { + type = type.ToLower(); + uint ipid = properties.Control.IpIdInt; + + DmMDMnxn chassis = null; + switch (type) { + case "dmmd8x8": + chassis = new DmMd8x8(ipid, Global.ControlSystem); + break; + case "dmmd8x8rps": + chassis = new DmMd8x8rps(ipid, Global.ControlSystem); + break; + case "dmmd8x8cpu3": + chassis = new DmMd8x8Cpu3(ipid, Global.ControlSystem); + break; + case "dmmd8x8cpu3rps": + chassis = new DmMd8x8Cpu3rps(ipid, Global.ControlSystem); + break; + case "dmmd16x16": + chassis = new DmMd16x16(ipid, Global.ControlSystem); + break; + case "dmmd16x16rps": + chassis = new DmMd16x16rps(ipid, Global.ControlSystem); + break; + case "dmmd16x16cpu3": + chassis = new DmMd16x16Cpu3(ipid, Global.ControlSystem); + break; + case "dmmd16x16cpu3rps": + chassis = new DmMd16x16Cpu3rps(ipid, Global.ControlSystem); + break; + case "dmmd32x32": + chassis = new DmMd32x32(ipid, Global.ControlSystem); + break; + case "dmmd32x32rps": + chassis = new DmMd32x32rps(ipid, Global.ControlSystem); + break; + case "dmmd32x32cpu3": + chassis = new DmMd32x32Cpu3(ipid, Global.ControlSystem); + break; + case "dmmd32x32cpu3rps": + chassis = new DmMd32x32Cpu3rps(ipid, Global.ControlSystem); + break; + } + + if (chassis == null) + return null; + + var controller = new DmChassisController(key, name, chassis); + + // add the cards and port names + foreach (var kvp in properties.InputSlots) + controller.AddInputCard(kvp.Value, kvp.Key); + + foreach (var kvp in properties.OutputSlots) + controller.AddOutputCard(kvp.Value, kvp.Key); + + foreach (var kvp in properties.VolumeControls) + { + // get the card + // check it for an audio-compatible type + // make a something-something that will make it work + // retire to mountain village + var outNum = kvp.Key; + var card = controller.Chassis.Outputs[outNum].Card; + Audio.Output audio = null; + if (card is DmcHdo) + audio = (card as DmcHdo).Audio; + else if (card is Dmc4kHdo) + audio = (card as Dmc4kHdo).Audio; + if (audio == null) + continue; + + // wire up the audio to something here... + controller.AddVolumeControl(outNum, audio); + } + + controller.InputNames = properties.InputNames; + controller.OutputNames = properties.OutputNames; + + if (!string.IsNullOrEmpty(properties.NoRouteText)) + { + controller.NoRouteText = properties.NoRouteText; + Debug.Console(1, controller, "Setting No Route Text value to: {0}", controller.NoRouteText); + } + else + { + Debug.Console(1, controller, "NoRouteText not specified. Defaulting to blank string.", controller.NoRouteText); + } + + controller.PropertiesConfig = properties; + return controller; + } + catch (Exception e) + { + Debug.Console(0, "Error creating DM chassis:\r{0}", e); + } + + return null; + } + + /// + /// + /// + /// + /// + /// + public DmChassisController(string key, string name, DmMDMnxn chassis) + : base(key, name, chassis) + { + Chassis = chassis; + InputPorts = new RoutingPortCollection(); + OutputPorts = new RoutingPortCollection(); + VolumeControls = new Dictionary(); + TxDictionary = new Dictionary(); + RxDictionary = new Dictionary(); + IsOnline.OutputChange += new EventHandler(IsOnline_OutputChange); + Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); + Chassis.DMSystemChange += new DMSystemEventHandler(Chassis_DMSystemChange); + Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange); + VideoOutputFeedbacks = new Dictionary(); + AudioOutputFeedbacks = new Dictionary(); + UsbOutputRoutedToFeebacks = new Dictionary(); + UsbInputRoutedToFeebacks = new Dictionary(); + OutputDisabledByHdcpFeedbacks = new Dictionary(); + VideoInputSyncFeedbacks = new Dictionary(); + InputNameFeedbacks = new Dictionary(); + OutputNameFeedbacks = new Dictionary(); + OutputVideoRouteNameFeedbacks = new Dictionary(); + OutputAudioRouteNameFeedbacks = new Dictionary(); + InputEndpointOnlineFeedbacks = new Dictionary(); + OutputEndpointOnlineFeedbacks = new Dictionary(); + + SystemIdFeebdack = new IntFeedback(() => { return (Chassis as DmMDMnxn).SystemIdFeedback.UShortValue; }); + SystemIdBusyFeedback = new BoolFeedback(() => { return (Chassis as DmMDMnxn).SystemIdBusy.BoolValue; }); + EnableAudioBreakawayFeedback = + new BoolFeedback(() => (Chassis as DmMDMnxn).EnableAudioBreakawayFeedback.BoolValue); + EnableUsbBreakawayFeedback = + new BoolFeedback(() => (Chassis as DmMDMnxn).EnableUSBBreakawayFeedback.BoolValue); + + InputCardHdcpCapabilityFeedbacks = new Dictionary(); + InputCardHdcpCapabilityTypes = new Dictionary(); + + for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) + { + var tempX = x; + + if (Chassis.Outputs[tempX] != null) + { + VideoOutputFeedbacks[tempX] = new IntFeedback(() => { + if (Chassis.Outputs[tempX].VideoOutFeedback != null) + return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; + + return 0; + }); + AudioOutputFeedbacks[tempX] = new IntFeedback(() => { + if (Chassis.Outputs[tempX].AudioOutFeedback != null) + return (ushort)Chassis.Outputs[tempX].AudioOutFeedback.Number; + + return 0; + }); + UsbOutputRoutedToFeebacks[tempX] = new IntFeedback(() => { + if (Chassis.Outputs[tempX].USBRoutedToFeedback != null) + return (ushort)Chassis.Outputs[tempX].USBRoutedToFeedback.Number; + + return 0; + }); + + OutputNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Outputs[tempX].NameFeedback != null) + return Chassis.Outputs[tempX].NameFeedback.StringValue; + + return ""; + }); + OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Outputs[tempX].VideoOutFeedback != null) + return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue; + + return NoRouteText; + }); + OutputAudioRouteNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Outputs[tempX].AudioOutFeedback != null) + return Chassis.Outputs[tempX].AudioOutFeedback.NameFeedback.StringValue; + + return NoRouteText; + }); + OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => Chassis.Outputs[tempX].EndpointOnlineFeedback); + + OutputDisabledByHdcpFeedbacks[tempX] = new BoolFeedback(() => { + var output = Chassis.Outputs[tempX]; + + var hdmiTxOutput = output as Card.HdmiTx; + if (hdmiTxOutput != null) + return hdmiTxOutput.HdmiOutput.DisabledByHdcp.BoolValue; + + var dmHdmiOutput = output as Card.DmHdmiOutput; + if (dmHdmiOutput != null) + return dmHdmiOutput.DisabledByHdcpFeedback.BoolValue; + + var dmsDmOutAdvanced = output as Card.DmsDmOutAdvanced; + if (dmsDmOutAdvanced != null) + return dmsDmOutAdvanced.DisabledByHdcpFeedback.BoolValue; + + var dmps3HdmiAudioOutput = output as Card.Dmps3HdmiAudioOutput; + if (dmps3HdmiAudioOutput != null) + return dmps3HdmiAudioOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + var dmps3HdmiOutput = output as Card.Dmps3HdmiOutput; + if (dmps3HdmiOutput != null) + return dmps3HdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + var dmps3HdmiOutputBackend = output as Card.Dmps3HdmiOutputBackend; + if (dmps3HdmiOutputBackend != null) + return dmps3HdmiOutputBackend.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + // var hdRx4kX10HdmiOutput = output as HdRx4kX10HdmiOutput; + // if (hdRx4kX10HdmiOutput != null) + // return hdRx4kX10HdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + // var hdMdNxMHdmiOutput = output as HdMdNxMHdmiOutput; + // if (hdMdNxMHdmiOutput != null) + // return hdMdNxMHdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + return false; + }); + } + + if (Chassis.Inputs[tempX] != null) + { + UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => { + if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) + return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; + + return 0; + }); + VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => { + if (Chassis.Inputs[tempX].VideoDetectedFeedback != null) + return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue; + + return false; + }); + InputNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Inputs[tempX].NameFeedback != null) + return Chassis.Inputs[tempX].NameFeedback.StringValue; + + return ""; + }); + + InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => { return Chassis.Inputs[tempX].EndpointOnlineFeedback; }); + + InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() => { + var inputCard = Chassis.Inputs[tempX]; + + if (inputCard.Card is DmcHd) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + + if ((inputCard.Card as DmcHd).HdmiInput.HdcpSupportOnFeedback.BoolValue) + return 1; + return 0; + } + + if (inputCard.Card is DmcHdDsp) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + + if ((inputCard.Card as DmcHdDsp).HdmiInput.HdcpSupportOnFeedback.BoolValue) + return 1; + return 0; + } + if (inputCard.Card is Dmc4kHdBase) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; + return (int)(inputCard.Card as Dmc4kHdBase).HdmiInput.HdcpReceiveCapability; + } + if (inputCard.Card is Dmc4kCBase) + { + if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + return (int)(inputCard.Card as Dmc4kCBase).DmInput.HdcpReceiveCapability; + } + + if ((inputCard.Card as Dmc4kCBase).DmInput.HdcpSupportOnFeedback.BoolValue) + return 1; + return 0; + } + if (inputCard.Card is Dmc4kCDspBase) + { + if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + return (int)(inputCard.Card as Dmc4kCDspBase).DmInput.HdcpReceiveCapability; + } + + if ((inputCard.Card as Dmc4kCDspBase).DmInput.HdcpSupportOnFeedback.BoolValue) + return 1; + + return 0; + } + return 0; + }); + } + } + } + + private void ChassisOnBaseEvent(GenericBase device, BaseEventArgs args) + { + + } + + /// + /// + /// + /// + /// + public void AddInputCard(string type, uint number) + { + Debug.Console(2, this, "Adding input card '{0}', slot {1}", type, number); + + type = type.ToLower(); + + if (type == "dmchd") + { + var inputCard = new DmcHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmchddsp") + { + var inputCard = new DmcHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmc4khd") + { + var inputCard = new Dmc4kHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmc4khddsp") + { + var inputCard = new Dmc4kHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmc4kzhd") + { + var inputCard = new Dmc4kzHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmc4kzhddsp") + { + var inputCard = new Dmc4kzHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmcc") + { + var inputCard = new DmcC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmccdsp") + { + var inputCard = new DmcCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmc4kc") + { + var inputCard = new Dmc4kC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmc4kcdsp") + { + var inputCard = new Dmc4kCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmc4kzc") + { + var inputCard = new Dmc4kzC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmc4kzcdsp") + { + var inputCard = new Dmc4kzCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmccat") + { + new DmcCat(number, this.Chassis); + AddDmInCardPorts(number); + } + else if (type == "dmccatdsp") + { + new DmcCatDsp(number, this.Chassis); + AddDmInCardPorts(number); + } + else if (type == "dmcs") + { + new DmcS(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + } + else if (type == "dmcsdsp") + { + new DmcSDsp(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + } + else if (type == "dmcs2") + { + new DmcS2(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + } + else if (type == "dmcs2dsp") + { + new DmcS2Dsp(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + } + else if (type == "dmcsdi") + { + new DmcSdi(number, Chassis); + AddInputPortWithDebug(number, "sdiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi); + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "sdiOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Sdi, null); + AddInCardHdmiAndAudioLoopPorts(number); + } + else if (type == "dmcdvi") + { + new DmcDvi(number, Chassis); + AddInputPortWithDebug(number, "dviIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Dvi); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcvga") + { + new DmcVga(number, Chassis); + AddInputPortWithDebug(number, "vgaIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Vga); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcvidbnc") + { + new DmcVidBnc(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcvidrcaa") + { + new DmcVidRcaA(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcvidrcad") + { + new DmcVidRcaD(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcvid4") + { + new DmcVid4(number, Chassis); + AddInputPortWithDebug(number, "compositeIn1", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInputPortWithDebug(number, "compositeIn2", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInputPortWithDebug(number, "compositeIn3", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInputPortWithDebug(number, "compositeIn4", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcstr") + { + new DmcStr(number, Chassis); + AddInputPortWithDebug(number, "streamIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming); + AddInCardHdmiAndAudioLoopPorts(number); + } + } + + void AddDmInCardPorts(uint number) + { + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat); + AddInCardHdmiAndAudioLoopPorts(number); + } + + void AddDmInCardPorts(uint number, ICec cecPort) + { + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort); + AddInCardHdmiAndAudioLoopPorts(number); + } + + void AddHdmiInCardPorts(uint number, ICec cecPort) + { + AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort); + AddInCardHdmiAndAudioLoopPorts(number); + } + + void AddInCardHdmiAndAudioLoopPorts(uint number) + { + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null); + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "audioLoopOut", eRoutingSignalType.Audio, eRoutingPortConnectionType.Hdmi, null); + } + + void AddInCardHdmiLoopPort(uint number) + { + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null); + } + + /// + /// + /// + /// + /// + public void AddOutputCard(string type, uint number) + { + type = type.ToLower(); + + Debug.Console(2, this, "Adding output card '{0}', slot {1}", type, number); + if (type == "dmc4khdo") + { + var outputCard = new Dmc4kHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); + } + else if (type == "dmc4kzhdo") + { + var outputCard = new Dmc4kzHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); + } + else if (type == "dmchdo") + { + var outputCard = new DmcHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); + } + else if (type == "dmc4kcohd") + { + var outputCard = new Dmc4kCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + else if (type == "dmc4kzcohd") + { + var outputCard = new Dmc4kzCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + else if (type == "dmccohd") + { + var outputCard = new DmcCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + else if (type == "dmccatohd") + { + var outputCard = new DmcCatoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + else if (type == "dmcsohd") + { + var outputCard = new DmcSoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmMmFiber, 2 * (number - 1) + 1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmMmFiber, 2 * (number - 1) + 2); + } + else if (type == "dmcs2ohd") + { + var outputCard = new DmcS2oHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmSmFiber, 2 * (number - 1) + 1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmSmFiber, 2 * (number - 1) + 2); + } + else if (type == "dmcstro") + { + var outputCard = new DmcStroSingle(number, Chassis); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "streamOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Streaming, 2 * (number - 1) + 1); + } + + else + Debug.Console(1, this, " WARNING: Output card type '{0}' is not available", type); + } + + void AddDmcHdoPorts(uint number, ICec cecPort1, ICec cecPort2) + { + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut1", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, + 2 * (number - 1) + 1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 2, cecPort2); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut2", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, + 2 * (number - 1) + 2); + } + + void AddDmcCoPorts(uint number, ICec cecPort1) + { + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, 2 * (number - 1) + 1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, 2 * (number - 1) + 2); + } + + /// + /// Adds InputPort + /// + void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) + { + var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); + Debug.Console(2, this, "Adding input port '{0}'", portKey); + var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); + + InputPorts.Add(inputPort); + } + + /// + /// Adds InputPort and sets Port as ICec object + /// + void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort) + { + var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); + Debug.Console(2, this, "Adding input port '{0}'", portKey); + var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); + + if (cecPort != null) + inputPort.Port = cecPort; + + InputPorts.Add(inputPort); + } + + /// + /// Adds OutputPort + /// + void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) + { + var portKey = string.Format("{0}--{1}", cardName, portName); + Debug.Console(2, this, "Adding output port '{0}'", portKey); + OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)); + } + + /// + /// Adds OutputPort and sets Port as ICec object + /// + void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector, ICec cecPort) + { + var portKey = string.Format("{0}--{1}", cardName, portName); + Debug.Console(2, this, "Adding output port '{0}'", portKey); + var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this); + + if (cecPort != null) + outputPort.Port = cecPort; + + OutputPorts.Add(outputPort); + } + + /// + /// + /// + void AddVolumeControl(uint number, Audio.Output audio) + { + VolumeControls.Add(number, new DmCardAudioOutputController(audio)); + } + + //public void SetInputHdcpSupport(uint input, ePdtHdcpSupport hdcpSetting) + //{ + + //} + + void Chassis_DMSystemChange(Switch device, DMSystemEventArgs args) + { + switch (args.EventId) + { + case DMSystemEventIds.SystemIdEventId: + { + Debug.Console(2, this, "SystemIdEvent Value: {0}", (Chassis as DmMDMnxn).SystemIdFeedback.UShortValue); + SystemIdFeebdack.FireUpdate(); + break; + } + case DMSystemEventIds.SystemIdBusyEventId: + { + Debug.Console(2, this, "SystemIdBusyEvent State: {0}", (Chassis as DmMDMnxn).SystemIdBusy.BoolValue); + SystemIdBusyFeedback.FireUpdate(); + break; + } + case DMSystemEventIds.AudioBreakawayEventId: + { + Debug.Console(2, this, "AudioBreakaway Event: value: {0}", + (Chassis as DmMDMnxn).EnableAudioBreakawayFeedback.BoolValue); + EnableAudioBreakawayFeedback.FireUpdate(); + break; + } + case DMSystemEventIds.USBBreakawayEventId: + { + Debug.Console(2, this, "USBBreakaway Event: value: {0}", + (Chassis as DmMDMnxn).EnableUSBBreakawayFeedback.BoolValue); + EnableUsbBreakawayFeedback.FireUpdate(); + break; + } + } + } + + void Chassis_DMInputChange(Switch device, DMInputEventArgs args) + { + switch (args.EventId) + { + case DMInputEventIds.EndpointOnlineEventId: + { + Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); + InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.OnlineFeedbackEventId: + { + Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); + InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.VideoDetectedEventId: + { + Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number); + VideoInputSyncFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.InputNameEventId: + { + Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number); + InputNameFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.UsbRoutedToEventId: + { + Debug.Console(2, this, "DM Input {0} UsbRoutedToEventId", args.Number); + if (UsbInputRoutedToFeebacks[args.Number] != null) + UsbInputRoutedToFeebacks[args.Number].FireUpdate(); + else + Debug.Console(1, this, "No index of {0} found in UsbInputRoutedToFeedbacks"); + break; + } + case DMInputEventIds.HdcpCapabilityFeedbackEventId: + { + Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number); + if (InputCardHdcpCapabilityFeedbacks[args.Number] != null) + InputCardHdcpCapabilityFeedbacks[args.Number].FireUpdate(); + else + Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks"); + break; + } + default: + { + Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId); + break; + } + } + } + + /// + /// + void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) + { + var output = args.Number; + + switch (args.EventId) + { + case DMOutputEventIds.VolumeEventId: + { + if (VolumeControls.ContainsKey(output)) + { + VolumeControls[args.Number].VolumeEventFromChassis(); + } + + break; + } + case DMOutputEventIds.EndpointOnlineEventId: + { + Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. State: {1}", args.Number, + Chassis.Outputs[output].EndpointOnlineFeedback); + OutputEndpointOnlineFeedbacks[output].FireUpdate(); + break; + } + case DMOutputEventIds.OnlineFeedbackEventId: + { + Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}", args.Number, + Chassis.Outputs[output].EndpointOnlineFeedback); + OutputEndpointOnlineFeedbacks[output].FireUpdate(); + break; + } + case DMOutputEventIds.VideoOutEventId: + { + if (Chassis.Outputs[output].VideoOutFeedback != null) + Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].VideoOutFeedback.Number, output); + + if (VideoOutputFeedbacks.ContainsKey(output)) + VideoOutputFeedbacks[output].FireUpdate(); + + if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) + OutputVideoRouteNameFeedbacks[output].FireUpdate(); + + break; + } + case DMOutputEventIds.AudioOutEventId: + { + if (Chassis.Outputs[output].AudioOutFeedback != null) + Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].AudioOutFeedback.Number, output); + + if (AudioOutputFeedbacks.ContainsKey(output)) + AudioOutputFeedbacks[output].FireUpdate(); + + if (OutputAudioRouteNameFeedbacks.ContainsKey(output)) + OutputAudioRouteNameFeedbacks[output].FireUpdate(); + + break; + } + case DMOutputEventIds.OutputNameEventId: + { + Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output); + OutputNameFeedbacks[output].FireUpdate(); + break; + } + case DMOutputEventIds.UsbRoutedToEventId: + { + Debug.Console(2, this, "DM Output {0} UsbRoutedToEventId", args.Number); + UsbOutputRoutedToFeebacks[args.Number].FireUpdate(); + break; + } + case DMOutputEventIds.DisabledByHdcpEventId: + { + Debug.Console(2, this, "DM Output {0} DisabledByHdcpEventId", args.Number); + OutputDisabledByHdcpFeedbacks[args.Number].FireUpdate(); + break; + } + default: + { + Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", args.Number, args.EventId); + break; + } + } + } + + /// + /// + /// + /// + void StartOffTimer(PortNumberType pnt) + { + if (RouteOffTimers.ContainsKey(pnt)) + return; + RouteOffTimers[pnt] = new CTimer(o => { ExecuteSwitch(0, pnt.Number, pnt.Type); }, RouteOffTime); + } + + // Send out sigs when coming online + void IsOnline_OutputChange(object sender, EventArgs e) + { + if (IsOnline.BoolValue) + { + (Chassis as DmMDMnxn).EnableAudioBreakaway.BoolValue = true; + (Chassis as DmMDMnxn).EnableUSBBreakaway.BoolValue = true; + + + EnableAudioBreakawayFeedback.FireUpdate(); + EnableUsbBreakawayFeedback.FireUpdate(); + + if (InputNames != null) + foreach (var kvp in InputNames) + Chassis.Inputs[kvp.Key].Name.StringValue = kvp.Value; + if (OutputNames != null) + foreach (var kvp in OutputNames) + Chassis.Outputs[kvp.Key].Name.StringValue = kvp.Value; + } + } + + #region IRouting Members + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) + { + Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType); + + var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail + var output = Convert.ToUInt32(outputSelector); + + var chassisSize = (uint) Chassis.NumberOfInputs; //need this to determine USB routing values 8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 + //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 + //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 + + // Check to see if there's an off timer waiting on this and if so, cancel + var key = new PortNumberType(output, sigType); + if (input == 0) + { + StartOffTimer(key); + } + else + { + if (RouteOffTimers.ContainsKey(key)) + { + Debug.Console(2, this, "{0} cancelling route off due to new source", output); + RouteOffTimers[key].Stop(); + RouteOffTimers.Remove(key); + } + } + + var inCard = input == 0 ? null : Chassis.Inputs[input]; + var outCard = input == 0 ? null : Chassis.Outputs[output]; + + // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES + if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) + { + Chassis.VideoEnter.BoolValue = true; + Chassis.Outputs[output].VideoOut = inCard; + } + + if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio) + { + (Chassis as DmMDMnxn).AudioEnter.BoolValue = true; + Chassis.Outputs[output].AudioOut = inCard; + } + + if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) + { + //using base here because USB can be routed between 2 output cards or 2 input cards + DMInputOutputBase dmCard; + + Debug.Console(2, this, "Executing USB Output switch.\r\n in:{0} output: {1}", input, output); + + if (input > chassisSize) + { + //wanting to route an output to an output. Subtract chassis size and get output, unless it's 8x8 + //need this to determine USB routing values + //8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 + //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 + //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 + uint outputIndex; + + if (chassisSize == 8) + { + outputIndex = input - 16; + } + else + { + outputIndex = input - chassisSize; + } + dmCard = Chassis.Outputs[outputIndex]; + } + else + { + dmCard = inCard; + } + Chassis.USBEnter.BoolValue = true; + if (Chassis.Outputs[output] != null) + { + Debug.Console(2, this, "Routing USB for input {0} to {1}", Chassis.Outputs[input], dmCard); + Chassis.Outputs[output].USBRoutedTo = dmCard; + } + } + + if ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) + { + //using base here because USB can be routed between 2 output cards or 2 input cards + DMInputOutputBase dmCard; + + Debug.Console(2, this, "Executing USB Input switch.\r\n in:{0} output: {1}", input, output); + + if (output > chassisSize) + { + //wanting to route an input to an output. Subtract chassis size and get output, unless it's 8x8 + //need this to determine USB routing values + //8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 + //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 + //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 + uint outputIndex; + + if (chassisSize == 8) + { + outputIndex = input - 16; + } + else + { + outputIndex = input - chassisSize; + } + dmCard = Chassis.Outputs[outputIndex]; + } + else + { + dmCard = Chassis.Inputs[input]; + } + + + + Chassis.USBEnter.BoolValue = true; + + if (Chassis.Inputs[output] == null) + { + return; + } + Debug.Console(2, this, "Routing USB for input {0} to {1}", Chassis.Inputs[output], dmCard); + Chassis.Inputs[output].USBRoutedTo = dmCard; + } + } + #endregion + + #region IRoutingNumeric Members + + public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) + { + ExecuteSwitch(inputSelector, outputSelector, sigType); + } + + #endregion + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new DmChassisControllerJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + var chassis = Chassis as DmMDMnxn; + + IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + + trilist.SetUShortSigAction(joinMap.SystemId.JoinNumber, o => + { + if (chassis != null) + chassis.SystemId.UShortValue = o; + }); + + trilist.SetSigTrueAction(joinMap.SystemId.JoinNumber, () => + { + if (chassis != null) chassis.ApplySystemId(); + }); + + SystemIdFeebdack.LinkInputSig(trilist.UShortInput[joinMap.SystemId.JoinNumber]); + SystemIdBusyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SystemId.JoinNumber]); + + EnableAudioBreakawayFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAudioBreakaway.JoinNumber]); + EnableUsbBreakawayFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsbBreakaway.JoinNumber]); + + trilist.OnlineStatusChange += (o, a) => + { + if (!a.DeviceOnLine) return; + + EnableAudioBreakawayFeedback.FireUpdate(); + EnableUsbBreakawayFeedback.FireUpdate(); + SystemIdBusyFeedback.FireUpdate(); + SystemIdFeebdack.FireUpdate(); + }; + + // Link up outputs + for (uint i = 1; i <= Chassis.NumberOfOutputs; i++) + { + var ioSlot = i; + var ioSlotJoin = ioSlot - 1; + + // Control + trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)); + trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)); + trilist.SetUShortSigAction(joinMap.OutputUsb.JoinNumber + ioSlotJoin, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbOutput)); + trilist.SetUShortSigAction(joinMap.InputUsb.JoinNumber + ioSlotJoin, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbInput)); + + if (TxDictionary.ContainsKey(ioSlot)) + { + Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); + var txKey = TxDictionary[ioSlot]; + var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase; + + var advancedTxDevice = basicTxDevice as DmTxControllerBase; + + if (Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps + || Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps + || Chassis is DmMd32x32Cpu3 || Chassis is DmMd32x32Cpu3rps) + { + InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); + } + else + { + if (advancedTxDevice != null) + { + advancedTxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); + Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot); + } + else if (InputEndpointOnlineFeedbacks[ioSlot] != null) + { + Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot); + InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); + } + } + + if (basicTxDevice != null && advancedTxDevice == null) + trilist.BooleanInput[joinMap.TxAdvancedIsPresent.JoinNumber + ioSlotJoin].BoolValue = true; + + if (advancedTxDevice != null) + { + advancedTxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); + } + else if (advancedTxDevice == null || basicTxDevice != null) + { + Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot); + VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); + + var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; + if (inputPort != null) + { + Debug.Console(1, "Port value for input card {0} is set", ioSlot); + var port = inputPort.Port; + + if (port != null) + { + if (port is HdmiInputWithCEC) + { + Debug.Console(1, "Port is HdmiInputWithCec"); + + var hdmiInPortWCec = port as HdmiInputWithCEC; + + if (hdmiInPortWCec.HdcpSupportedLevel != eHdcpSupportedLevel.Unknown) + { + SetHdcpStateAction(true, hdmiInPortWCec, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); + } + + InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); + + if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) + trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = (ushort)InputCardHdcpCapabilityTypes[ioSlot]; + else + trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; + } + } + } + else + { + inputPort = InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)]; + + if (inputPort != null) + { + var port = inputPort.Port; + + if (port is DMInputPortWithCec) + { + Debug.Console(1, "Port is DMInputPortWithCec"); + + var dmInPortWCec = port as DMInputPortWithCec; + + if (dmInPortWCec != null) + { + SetHdcpStateAction(PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], dmInPortWCec, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); + } + + InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); + + if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) + trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = (ushort)InputCardHdcpCapabilityTypes[ioSlot]; + else + trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; + } + } + } + } + } + else + { + VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); + + var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; + if (inputPort != null) + { + var hdmiPort = inputPort.Port as EndpointHdmiInput; + + if (hdmiPort != null) + { + SetHdcpStateAction(true, hdmiPort, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); + InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); + } + } + } + + if (RxDictionary.ContainsKey(ioSlot)) + { + Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot); + var rxKey = RxDictionary[ioSlot]; + var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase; + var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase; + if (Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps + || Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps + || Chassis is DmMd32x32Cpu3 || Chassis is DmMd32x32Cpu3rps || hdBaseTDevice != null) + { + OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]); + } + else if (rxDevice != null) + { + rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]); + } + } + + // Feedback + VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo.JoinNumber + ioSlotJoin]); + AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + ioSlotJoin]); + UsbOutputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputUsb.JoinNumber + ioSlotJoin]); + UsbInputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.InputUsb.JoinNumber + ioSlotJoin]); + + OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]); + InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]); + OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + ioSlotJoin]); + OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames.JoinNumber + ioSlotJoin]); + + OutputDisabledByHdcpFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputDisabledByHdcp.JoinNumber + ioSlotJoin]); + } + } + + private void SetHdcpStateAction(bool hdcpTypeSimple, HdmiInputWithCEC port, uint join, BasicTriList trilist) + { + if (hdcpTypeSimple) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + port.HdcpReceiveCapability = (eHdcpCapabilityType)u; + }); + } + } + + private void SetHdcpStateAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist) + { + if (hdcpTypeSimple) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + port.HdcpCapability = (eHdcpCapabilityType)u; + }); + } + } + + private void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist) + { + if (!supportsHdcp2) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + port.HdcpReceiveCapability = (eHdcpCapabilityType)u; + }); + } + } + } + + public struct PortNumberType + { + public uint Number { get; private set; } + public eRoutingSignalType Type { get; private set; } + + public PortNumberType(uint number, eRoutingSignalType type) + : this() + { + Number = number; + Type = type; + } + } + + public class DmChassisControllerFactory : EssentialsDeviceFactory + { + public DmChassisControllerFactory() + { + TypeNames = new List() { "dmmd8x8", "dmmd8x8rps", "dmmd8x8cpu3", "dmmd8x8cpu3rps", + "dmmd16x16", "dmmd16x16rps", "dmmd16x16cpu3", "dmmd16x16cpu3rps", + "dmmd32x32", "dmmd32x32rps", "dmmd32x32cpu3", "dmmd32x32cpu3rps", + "dmmd64x64", "dmmd128x128" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + var type = dc.Type.ToLower(); + + Debug.Console(1, "Factory Attempting to create new DmChassisController Device"); + + if (type.StartsWith("dmmd8x") || type.StartsWith("dmmd16x") || type.StartsWith("dmmd32x")) + { + + var props = JsonConvert.DeserializeObject + (dc.Properties.ToString()); + return PepperDash.Essentials.DM.DmChassisController. + GetDmChassisController(dc.Key, dc.Name, type, props); + } + else if (type.StartsWith("dmmd128x") || type.StartsWith("dmmd64x")) + { + var props = JsonConvert.DeserializeObject + (dc.Properties.ToString()); + return PepperDash.Essentials.DM.DmBladeChassisController. + GetDmChassisController(dc.Key, dc.Name, type, props); + } + + return null; + } + } + +} + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index 78a6e565..ba12a129 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -116,8 +116,6 @@ - - diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs index b6508920..e02fe7f0 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs @@ -55,11 +55,29 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy } } - public GlsOccupancySensorBaseController(string key, string name, GlsOccupancySensorBase sensor) - : base(key, name, sensor) + public GlsOccupancySensorBaseController(string key, Func preActivationFunc, + DeviceConfig config) + : base(key, config.Name) { - OccSensor = sensor; - + + + AddPreActivationAction(() => + { + OccSensor = preActivationFunc(config); + + RegisterCrestronGenericBase(OccSensor); + + RegisterGlsOdtSensorBaseController(OccSensor); + + }); + } + + public GlsOccupancySensorBaseController(string key, string name) : base(key, name) {} + + protected void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor) + { + OccSensor = occSensor; + RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue); @@ -68,15 +86,18 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue); - PirSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue); + PirSensitivityInVacantStateFeedback = + new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue); - PirSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue); + PirSensitivityInOccupiedStateFeedback = + new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue); CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue); LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue); - GraceOccupancyDetectedFeedback = new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue); + GraceOccupancyDetectedFeedback = + new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue); RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue); @@ -84,9 +105,9 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue); - OccSensor.BaseEvent += new Crestron.SimplSharpPro.BaseEventHandler(OccSensor_BaseEvent); + OccSensor.BaseEvent += OccSensor_BaseEvent; - OccSensor.GlsOccupancySensorChange += new GlsOccupancySensorChangeEventHandler(OccSensor_GlsOccupancySensorChange); + OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange; } @@ -97,40 +118,56 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy /// protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args) { - if (args.EventId == GlsOccupancySensorBase.PirEnabledFeedbackEventId) - PirSensorEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId) - LedFlashEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId) - ShortTimeoutEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId) - PirSensitivityInOccupiedStateFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId) - PirSensitivityInVacantStateFeedback.FireUpdate(); + switch (args.EventId) + { + case GlsOccupancySensorBase.PirEnabledFeedbackEventId: + PirSensorEnabledFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId: + LedFlashEnabledFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId: + ShortTimeoutEnabledFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId: + PirSensitivityInOccupiedStateFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId: + PirSensitivityInVacantStateFeedback.FireUpdate(); + break; + } } protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) { Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId); - if (args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId - || args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId) + switch (args.EventId) { - Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue); - RoomIsOccupiedFeedback.FireUpdate(); + case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId: + case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId: + Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue); + RoomIsOccupiedFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.TimeoutFeedbackEventId: + CurrentTimeoutFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId: + LocalTimoutFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId: + GraceOccupancyDetectedFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.RawOccupancyFeedbackEventId: + RawOccupancyFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId: + InternalPhotoSensorValue.FireUpdate(); + break; + case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId: + ExternalPhotoSensorValue.FireUpdate(); + break; } - else if (args.EventId == GlsOccupancySensorBase.TimeoutFeedbackEventId) - CurrentTimeoutFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.TimeoutLocalFeedbackEventId) - LocalTimoutFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId) - GraceOccupancyDetectedFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.RawOccupancyFeedbackEventId) - RawOccupancyFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId) - InternalPhotoSensorValue.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId) - ExternalPhotoSensorValue.FireUpdate(); } public void SetTestMode(bool mode) @@ -373,27 +410,51 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy { LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); } - } - public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory - { - public GlsOccupancySensorBaseControllerFactory() + #region PreActivation + + private static GlsOirCCn GetGlsOirCCn(DeviceConfig dc) { - TypeNames = new List() { "glsoirccn" }; + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; + + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey); + return new GlsOirCCn(cresnetId, Global.ControlSystem); + } + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as ICresnetBridge; + + if (cresnetBridge != null) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey); + return new GlsOirCCn(cresnetId, cresnetBridge.Branches[branchId]); + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; } + #endregion - public override EssentialsDevice BuildDevice(DeviceConfig dc) + public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory { - Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + public GlsOccupancySensorBaseControllerFactory() + { + TypeNames = new List() { "glsoirccn" }; + } - var key = dc.Key; - var name = dc.Name; - var comm = CommFactory.GetControlPropertiesConfig(dc); - GlsOccupancySensorBase occSensor = new GlsOirCCn(comm.CresnetIdInt, Global.ControlSystem); + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + + return new GlsOccupancySensorBaseController(dc.Key, GetGlsOirCCn, dc); + } - return new GlsOccupancySensorBaseController(key, name, occSensor); } } + + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs index 26fec016..3fde82b0 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs @@ -35,26 +35,35 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy public BoolFeedback RawOccupancyUsFeedback { get; private set; } - public GlsOdtOccupancySensorController(string key, string name, GlsOdtCCn sensor) - : base(key, name, sensor) + public GlsOdtOccupancySensorController(string key, Func preActivationFunc, + DeviceConfig config) + : base(key, config.Name) { - OccSensor = sensor; + AddPreActivationAction(() => + { + OccSensor = preActivationFunc(config); - AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue); + RegisterCrestronGenericBase(OccSensor); - OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue); + RegisterGlsOdtSensorBaseController(OccSensor); - UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UsAEnabledFeedback.BoolValue); + AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue); - UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UsBEnabledFeedback.BoolValue); + OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue); - RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyPirFeedback.BoolValue); + UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UsAEnabledFeedback.BoolValue); - RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyUsFeedback.BoolValue); + UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UsBEnabledFeedback.BoolValue); - UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInVacantStateFeedback.UShortValue); + RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyPirFeedback.BoolValue); - UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue); + RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyUsFeedback.BoolValue); + + UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInVacantStateFeedback.UShortValue); + + UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue); + + }); } /// @@ -160,38 +169,51 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy { LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); } - } - public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory - { - public GlsOdtOccupancySensorControllerFactory() + #region PreActivation + + private static GlsOdtCCn GetGlsOdtCCn(DeviceConfig dc) { - TypeNames = new List() { "glsodtccn" }; - } + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); - - var typeName = dc.Type.ToLower(); - var key = dc.Key; - var name = dc.Name; - var comm = CommFactory.GetControlPropertiesConfig(dc); - - var occSensor = new GlsOdtCCn(comm.CresnetIdInt, Global.ControlSystem); - - if (occSensor != null) + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) { - return new GlsOdtOccupancySensorController(key, name, occSensor); + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey); + return new GlsOdtCCn(cresnetId, Global.ControlSystem); } - else + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as ICresnetBridge; + + if (cresnetBridge != null) { - Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key); - return null; + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey); + return new GlsOdtCCn(cresnetId, cresnetBridge.Branches[branchId]); + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; + } + #endregion + + public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory + { + public GlsOdtOccupancySensorControllerFactory() + { + TypeNames = new List() { "glsodtccn" }; } + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + + return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc); + } + } } + + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/PartitionSensor/GlsPartitionSensorControllerFactory.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/PartitionSensor/GlsPartitionSensorControllerFactory.cs deleted file mode 100644 index a60637f7..00000000 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/PartitionSensor/GlsPartitionSensorControllerFactory.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -using Crestron.SimplSharpPro.GeneralIO; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; - -namespace PepperDash.Essentials.Devices.Common.PartitionSensor -{ - public class GlsPartitionSensorControllerFactory : EssentialsDeviceFactory - { - public GlsPartitionSensorControllerFactory() - { - TypeNames = new List() { "glspartcn" }; - } - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(2, "Factory Attempting to create new GLS-PART-CN Device"); - - var comm = CommFactory.GetControlPropertiesConfig(dc); - if (comm == null) - { - Debug.Console(0, "ERROR: Control Properties Config for {0} is null", dc.Key); - return null; - } - - var sensor = new GlsPartCn(comm.CresnetIdInt, Global.ControlSystem); - return new GlsPartitionSensorController(dc.Key, dc.Name, sensor); - } - } -} \ No newline at end of file