From 448b408f940d386fdef2d92726ab9680dc03955d Mon Sep 17 00:00:00 2001 From: Jason T Alborough Date: Tue, 17 Jul 2018 08:05:02 -0400 Subject: [PATCH] Merges Essentials bridges proof of concept work into new BB.org repo --- .../Bridges/Bridges.BridgeFactory.cs | 69 +++++++++ .../Bridges/EssentialComms.cs | 144 ++++++++++++++++++ PepperDashEssentials/Bridges/EssentialDM.cs | 140 +++++++++++++++++ .../Factories/DmFactory.cs | 10 ++ PepperDashEssentials/ControlSystem.cs | 8 +- .../PepperDashEssentials.csproj | 3 + essentials-framework | 2 +- 7 files changed, 372 insertions(+), 4 deletions(-) create mode 100644 PepperDashEssentials/Bridges/Bridges.BridgeFactory.cs create mode 100644 PepperDashEssentials/Bridges/EssentialComms.cs create mode 100644 PepperDashEssentials/Bridges/EssentialDM.cs diff --git a/PepperDashEssentials/Bridges/Bridges.BridgeFactory.cs b/PepperDashEssentials/Bridges/Bridges.BridgeFactory.cs new file mode 100644 index 00000000..d84e30ee --- /dev/null +++ b/PepperDashEssentials/Bridges/Bridges.BridgeFactory.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Core; +using PepperDash.Essentials.Core.Routing; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.EthernetCommunication; + +namespace PepperDash.Essentials { + public class BridgeFactory { + public static IKeyed GetDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc) { + // ? why is this static JTA 2018-06-13? + + var key = dc.Key; + var name = dc.Name; + var type = dc.Type; + var properties = dc.Properties; + var propAnon = new { }; + JsonConvert.DeserializeAnonymousType(dc.Properties.ToString(), propAnon); + + var typeName = dc.Type.ToLower(); + var groupName = dc.Group.ToLower(); + + Debug.Console(0, "Name {0}, Key {1}, Type {2}, Properties {3}", name, key, type, properties.ToString()); + if (typeName == "essentialdm") { + return new EssentialDM(key, name, properties); + } else if (typeName == "essentialcomm") { + + Debug.Console(0, "Launch Essential Comm"); + return new EssentialComm(key, name, properties); + + } + return null; + } + } + public class BridgeApiEisc { + public uint Ipid; + public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc; + public BridgeApiEisc(string ipid) { + Ipid = (UInt32)int.Parse(ipid, System.Globalization.NumberStyles.HexNumber); + Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(Ipid, "127.0.0.2", Global.ControlSystem); + Eisc.Register(); + Eisc.SigChange += Eisc_SigChange; + Debug.Console(0, "BridgeApiEisc Created at Ipid {0}", ipid); + } + void Eisc_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args) { + if (Debug.Level >= 1) + Debug.Console(2, "DDVC EISC change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue); + var uo = args.Sig.UserObject; + if (uo is Action) + (uo as Action)(args.Sig.BoolValue); + else if (uo is Action) + (uo as Action)(args.Sig.UShortValue); + else if (uo is Action) + (uo as Action)(args.Sig.StringValue); + } + } + + } + + + + \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/EssentialComms.cs b/PepperDashEssentials/Bridges/EssentialComms.cs new file mode 100644 index 00000000..25ca8bfa --- /dev/null +++ b/PepperDashEssentials/Bridges/EssentialComms.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Core; +using PepperDash.Essentials.Core.Routing; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.EthernetCommunication; +using Crestron.SimplSharpPro.CrestronThread; + +namespace PepperDash.Essentials { + public class EssentialCommConfig { + public string[] EiscApiIpids; + public EssentialCommCommConnectionConfigs[] CommConnections; + } + public class EssentialCommCommConnectionConfigs { + public uint joinNumber {get; set; } + public EssentialsControlPropertiesConfig control { get; set; } + } + + public class EssentialCommsPort { + public IBasicCommunication Comm; + public IntFeedback StatusFeedback; + public BoolFeedback ConnectedFeedback; + public List Outputs = new List(); + public String RxBuffer; + public EssentialCommsPort(EssentialsControlPropertiesConfig config, string keyPrefix) { + Comm = CommFactory.CreateCommForConfig(config, keyPrefix); + // var PortGather = new CommunicationGather(Comm, config.EndOfLineChar); + Comm.TextReceived += new EventHandler(Communication_TextReceived); + + var socket = Comm as ISocketStatus; + StatusFeedback = new IntFeedback(() => { return (int)socket.ClientStatus; }); + ConnectedFeedback = new BoolFeedback(() => { return Comm.IsConnected; }); + + if (socket != null) { + socket.ConnectionChange += new EventHandler(socket_ConnectionChange); + } else { + } + + } + void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) { + StatusFeedback.FireUpdate(); + ConnectedFeedback.FireUpdate(); + if (e.Client.IsConnected) { + // Tasks on connect + } else { + // Cleanup items from this session + } + } + void Communication_TextReceived(object sender, GenericCommMethodReceiveTextArgs args) { + try { + foreach (var Output in Outputs) { + Output.Api.Eisc.StringInput[Output.Join].StringValue = args.Text; + } + + } + catch (Exception) { + throw new FormatException(string.Format("ERROR:{0}")); + } + } + } + + public class EssentialComm : Device { + public EssentialCommConfig Properties; + + public CommunicationGather PortGather { get; private set; } + public List Apis {get; set;} + public Dictionary CommFeedbacks {get; private set; } + public StatusMonitorBase CommunicationMonitor { get; private set; } + public Dictionary CommDictionary { get; private set; } + + public EssentialComm(string key, string name, JToken properties) : base(key, name) { + Properties = JsonConvert.DeserializeObject(properties.ToString()); + CommFeedbacks = new Dictionary(); + CommDictionary = new Dictionary(); + Apis = new List(); + int commNumber = 1; + foreach (var commConfig in Properties.CommConnections) { + var commPort = new EssentialCommsPort(commConfig.control, string.Format("{0}-{1}", this.Key, commConfig.joinNumber)); + CommDictionary.Add(commConfig.joinNumber, commPort); + + commNumber++; + } + + foreach (var Ipid in Properties.EiscApiIpids) { + var ApiEisc = new BridgeApiEisc(Ipid); + Apis.Add(ApiEisc); + foreach (var commConnection in CommDictionary) { + Debug.Console(0, "Joining Api{0} to comm {1}", Ipid, commConnection.Key); + var tempComm = commConnection.Value; + var tempJoin = (uint)commConnection.Key; + EssentialComApiMap ApiMap = new EssentialComApiMap(ApiEisc, (uint)tempJoin); + + tempComm.Outputs.Add(ApiMap); + // Check for ApiMap Overide Values here + + ApiEisc.Eisc.SetBoolSigAction(tempJoin, b => {if (b) { tempComm.Comm.Connect(); } else { tempComm.Comm.Disconnect(); }}); + ApiEisc.Eisc.SetStringSigAction(tempJoin, s => tempComm.Comm.SendText(s)); + + tempComm.StatusFeedback.LinkInputSig(ApiEisc.Eisc.UShortInput[tempJoin]); + tempComm.ConnectedFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[tempJoin]); + + + + } + ApiEisc.Eisc.Register(); + } + } + + + + public override bool CustomActivate() + { + try { + + + + Debug.Console(0, "Name {0} Activated", this.Name); + return true; + } + catch (Exception e) { + Debug.Console(0, "BRidge {0}", e); + return false; + } + } + + + } + public class EssentialComApiMap { + public uint Join; + public BridgeApiEisc Api; + public uint connectJoin; + public EssentialComApiMap(BridgeApiEisc api, uint join) { + Join = join; + Api = api; + } + } + } \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/EssentialDM.cs b/PepperDashEssentials/Bridges/EssentialDM.cs new file mode 100644 index 00000000..48d93e5c --- /dev/null +++ b/PepperDashEssentials/Bridges/EssentialDM.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.DM; +using PepperDash.Core; +using PepperDash.Essentials.Core.Routing; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.EthernetCommunication; +using Crestron.SimplSharpPro.DM; + +namespace PepperDash.Essentials { + public class EssentialDM : PepperDash.Core.Device { + public EssentialDMProperties Properties; + public List BridgeApiEiscs; + private PepperDash.Essentials.DM.DmChassisController DmSwitch; + private EssentialDMApiMap ApiMap = new EssentialDMApiMap(); + public EssentialDM(string key, string name, JToken properties) + : base(key, name) { + Properties = JsonConvert.DeserializeObject(properties.ToString()); + + + } + public override bool CustomActivate() { + // Create EiscApis + try { + foreach (var device in DeviceManager.AllDevices) { + if (device.Key == this.Properties.connectionDeviceKey) { + Debug.Console(2, "deviceKey {0} Matches", device.Key); + DmSwitch = DeviceManager.GetDeviceForKey(device.Key) as PepperDash.Essentials.DM.DmChassisController; + + } + + + else { + Debug.Console(2, "deviceKey {0} doesn't match", device.Key); + } + } + if (Properties.EiscApiIpids != null) { + + + foreach (string Ipid in Properties.EiscApiIpids) { + var ApiEisc = new BridgeApiEisc(Ipid); + for (uint x = 1; x <= DmSwitch.Chassis.NumberOfInputs;x++ ) { + uint tempX = x; + Debug.Console(2, "Creating EiscActions {0}", tempX); + + + ApiEisc.Eisc.SetUShortSigAction(ApiMap.OutputVideoRoutes[tempX], u => DmSwitch.ExecuteSwitch(u, tempX, eRoutingSignalType.Video)); + ApiEisc.Eisc.SetUShortSigAction(ApiMap.OutputAudioRoutes[tempX], u => DmSwitch.ExecuteSwitch(u, tempX, eRoutingSignalType.Audio)); + + if (DmSwitch.TxDictionary.ContainsKey(tempX)) { + Debug.Console(2, "Creating Tx Feedbacks {0}", tempX); + var TxKey = DmSwitch.TxDictionary[tempX]; + var TxDevice = DeviceManager.GetDeviceForKey(TxKey) as DmTxControllerBase; + TxDevice.IsOnline.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.TxOnlineStatus[tempX]]); + TxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.TxVideoSyncStatus[tempX]]); + ApiEisc.Eisc.SetUShortSigAction(901, u => TxDevice.SetHdcpSupport((eHdcpSupportMode)(u))); + } else { + DmSwitch.VideoInputSyncFeedbacks[tempX].LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.TxVideoSyncStatus[tempX]]); + } + if (DmSwitch.RxDictionary.ContainsKey(tempX)) { + Debug.Console(2, "Creating Rx Feedbacks {0}", tempX); + var RxKey = DmSwitch.RxDictionary[tempX]; + var RxDevice = DeviceManager.GetDeviceForKey(RxKey) as DmRmcControllerBase; + RxDevice.IsOnline.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.RxOnlineStatus[tempX]]); + } + // DmSwitch.InputEndpointOnlineFeedbacks[(ushort)tempOutputNum].LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.OutputVideoRoutes[tempOutputNum]]); + DmSwitch.VideoOutputFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.OutputVideoRoutes[tempX]]); + DmSwitch.AudioOutputFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.OutputAudioRoutes[tempX]]); + DmSwitch.InputNameFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.InputNames[tempX]]); + DmSwitch.OutputNameFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.OutputNames[tempX]]); + DmSwitch.OutputRouteNameFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.OutputRouteNames[tempX]]); + } + DmSwitch.IsOnline.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.ChassisOnline]); + ApiEisc.Eisc.Register(); + } + } + + + + Debug.Console(2, "Name {0} Activated", this.Name); + return true; + } + catch (Exception e) { + Debug.Console(2, "BRidge {0}", e); + return false; + } + } + } + public class EssentialDMProperties { + public string connectionDeviceKey; + public string[] EiscApiIpids; + + + } + + + public class EssentialDMApiMap { + public ushort ChassisOnline = 11; + public Dictionary OutputVideoRoutes; + public Dictionary OutputAudioRoutes; + public Dictionary TxOnlineStatus; + public Dictionary RxOnlineStatus; + public Dictionary TxVideoSyncStatus; + public Dictionary InputNames; + public Dictionary OutputNames; + public Dictionary OutputRouteNames; + + public EssentialDMApiMap() { + OutputVideoRoutes = new Dictionary(); + OutputAudioRoutes = new Dictionary(); + TxOnlineStatus = new Dictionary(); + RxOnlineStatus = new Dictionary(); + TxVideoSyncStatus = new Dictionary(); + InputNames = new Dictionary(); + OutputNames = new Dictionary(); + OutputRouteNames = new Dictionary(); + for (uint x = 1; x <= 200; x++) { + // Debug.Console(0, "Init Value {0}", x); + uint tempNum = x; + + OutputVideoRoutes[tempNum] = (ushort)(tempNum + 100); + OutputAudioRoutes[tempNum] = (ushort)(tempNum + 300); + TxOnlineStatus[tempNum] = (ushort)(tempNum + 500); + RxOnlineStatus[tempNum] = (ushort)(tempNum + 700); + TxVideoSyncStatus[tempNum] = (ushort)(tempNum + 100); + InputNames[tempNum] = (ushort)(tempNum + 100); + OutputNames[tempNum] = (ushort)(tempNum + 300); + OutputRouteNames[tempNum] = (ushort)(tempNum + 2000); + } + } + } + } + \ No newline at end of file diff --git a/PepperDashEssentials/Configuration Original/Factories/DmFactory.cs b/PepperDashEssentials/Configuration Original/Factories/DmFactory.cs index 646cf1f3..ef2d1a03 100644 --- a/PepperDashEssentials/Configuration Original/Factories/DmFactory.cs +++ b/PepperDashEssentials/Configuration Original/Factories/DmFactory.cs @@ -80,6 +80,16 @@ namespace PepperDash.Essentials var dm = new DmMd8x8(ipId, Global.ControlSystem); //dev = new DmChassisController(devKey, devName, dm); } + else if (devType.Equals("dmmd16x16", StringComparison.OrdinalIgnoreCase)) + { + var dm = new DmMd16x16(ipId, Global.ControlSystem); + //dev = new DmChassisController(devKey, devName, dm); + } + else if (devType.Equals("dmmd32x32", StringComparison.OrdinalIgnoreCase)) + { + var dm = new DmMd32x32(ipId, Global.ControlSystem); + //dev = new DmChassisController(devKey, devName, dm); + } } catch (Exception e) { diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 06c63c05..a607ee5b 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -207,8 +207,9 @@ namespace PepperDash.Essentials /// public void LoadDevices() { - // Build the processor wrapper class - DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor")); +# warning Missing PepperDash.Essentials.Core.Devices.CrestronProcessor("processor")); + // Build the processor wrapper class + // DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor")); foreach (var devConf in ConfigReader.ConfigObject.Devices) { @@ -237,7 +238,8 @@ namespace PepperDash.Essentials newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf); if (newDev == null) newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf); - + if (newDev == null) + newDev = PepperDash.Essentials.BridgeFactory.GetDevice(devConf); if (newDev != null) DeviceManager.AddDevice(newDev); else diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index b4bfc66a..347b89c0 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -105,6 +105,7 @@ + @@ -121,6 +122,8 @@ + + diff --git a/essentials-framework b/essentials-framework index e13dcea5..13a51fcb 160000 --- a/essentials-framework +++ b/essentials-framework @@ -1 +1 @@ -Subproject commit e13dcea55066d8ebbe41089b6ab4597b94747207 +Subproject commit 13a51fcbf6466dede91bf7cc66184a557ba98996