diff --git a/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo b/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo index f1ca8e71..ddebd653 100644 Binary files a/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo and b/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo differ diff --git a/Essentials DM/Essentials_DM/Essentials_DM.projectinfo b/Essentials DM/Essentials_DM/Essentials_DM.projectinfo index b1abb622..6c769cce 100644 Binary files a/Essentials DM/Essentials_DM/Essentials_DM.projectinfo and b/Essentials DM/Essentials_DM/Essentials_DM.projectinfo differ diff --git a/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.projectinfo b/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.projectinfo index 0093d01b..42dae6e2 100644 Binary files a/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.projectinfo and b/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.projectinfo differ diff --git a/Essentials/PepperDashEssentials/ControlSystem.cs b/Essentials/PepperDashEssentials/ControlSystem.cs index 55248214..054077f5 100644 --- a/Essentials/PepperDashEssentials/ControlSystem.cs +++ b/Essentials/PepperDashEssentials/ControlSystem.cs @@ -1,164 +1,164 @@ -using System; -using System.Linq; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.CrestronThread; -using PepperDash.Core; -using PepperDash.Core.PortalSync; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Devices.Common; -using PepperDash.Essentials.DM; -using PepperDash.Essentials.Fusion; - -namespace PepperDash.Essentials -{ - public class ControlSystem : CrestronControlSystem - { - PepperDashPortalSyncClient PortalSync; - - public ControlSystem() - : base() - { - Thread.MaxNumberOfUserThreads = 400; - Global.ControlSystem = this; - DeviceManager.Initialize(this); - } - - /// - /// Git 'er goin' - /// - public override void InitializeSystem() - { - //CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Reloads configuration file", - // ConsoleAccessLevelEnum.AccessOperator); - //CrestronConsole.AddNewConsoleCommand(s => TearDown(), "ungo", "Reloads configuration file", - // ConsoleAccessLevelEnum.AccessOperator); - CrestronConsole.AddNewConsoleCommand(s => - { - foreach (var tl in TieLineCollection.Default) - CrestronConsole.ConsoleCommandResponse(" {0}\r", tl); - }, - "listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator); - - GoWithLoad(); - } - - /// - /// Do it, yo - /// - public void GoWithLoad() - { - var thread = new Thread(o => - { - try - { - CrestronConsole.AddNewConsoleCommand(EnablePortalSync, "portalsync", "Loads Portal Sync", - ConsoleAccessLevelEnum.AccessOperator); - - //PortalSync = new PepperDashPortalSyncClient(); - +using System; +using System.Linq; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.CrestronThread; +using PepperDash.Core; +using PepperDash.Core.PortalSync; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common; +using PepperDash.Essentials.DM; +using PepperDash.Essentials.Fusion; + +namespace PepperDash.Essentials +{ + public class ControlSystem : CrestronControlSystem + { + PepperDashPortalSyncClient PortalSync; + + public ControlSystem() + : base() + { + Thread.MaxNumberOfUserThreads = 400; + Global.ControlSystem = this; + DeviceManager.Initialize(this); + } + + /// + /// Git 'er goin' + /// + public override void InitializeSystem() + { + //CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Reloads configuration file", + // ConsoleAccessLevelEnum.AccessOperator); + //CrestronConsole.AddNewConsoleCommand(s => TearDown(), "ungo", "Reloads configuration file", + // ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(s => + { + foreach (var tl in TieLineCollection.Default) + CrestronConsole.ConsoleCommandResponse(" {0}\r", tl); + }, + "listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator); + + GoWithLoad(); + } + + /// + /// Do it, yo + /// + public void GoWithLoad() + { + var thread = new Thread(o => + { + try + { + CrestronConsole.AddNewConsoleCommand(EnablePortalSync, "portalsync", "Loads Portal Sync", + ConsoleAccessLevelEnum.AccessOperator); + + //PortalSync = new PepperDashPortalSyncClient(); + //Temp Cotija testing //CotijaInterfaceController CotijaInterface = new CotijaInterfaceController("WebClient1"); - //CotijaInterface.InitializeClient("http://192.168.1.105"); - - Debug.Console(0, "Starting Essentials load from configuration"); - ConfigReader.LoadConfig2(); - LoadDevices(); - LoadTieLines(); - LoadRooms(); - // FUSION - should go per room I believe. See CreateSystems in original Configuration.cs - // ??? - DeviceManager.ActivateAll(); - Debug.Console(0, "Essentials load complete\r" + - "-------------------------------------------------------------"); - } - catch (Exception e) - { - Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e); - } - return null; - }, null); - } - - public void EnablePortalSync(string s) - { - if (s.ToLower() == "enable") - { - CrestronConsole.ConsoleCommandResponse("Portal Sync features enabled"); - PortalSync = new PepperDashPortalSyncClient(); - } - } - - public void TearDown() - { - Debug.Console(0, "Tearing down existing system"); - DeviceManager.DeactivateAll(); - - TieLineCollection.Default.Clear(); - - foreach (var key in DeviceManager.GetDevices()) - DeviceManager.RemoveDevice(key); - - Debug.Console(0, "Tear down COMPLETE"); - } - - /// - /// Reads all devices from config and adds them to DeviceManager - /// - public void LoadDevices() - { - foreach (var devConf in ConfigReader.ConfigObject.Devices) - { - Debug.Console(0, "Creating device '{0}'", devConf.Key); - // Skip this to prevent unnecessary warnings - if (devConf.Key == "processor") - continue; - - // Try local factory first - var newDev = DeviceFactory.GetDevice(devConf); - - // Then associated library factories - if (newDev == null) - newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf); - - if (newDev != null) - DeviceManager.AddDevice(newDev); - else - Debug.Console(0, "WARNING: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key); - } - } - - /// - /// Helper method to load tie lines. This should run after devices have loaded - /// - public void LoadTieLines() - { - // Make this reusable by clearing the TieLineCollection - - var tlc = TieLineCollection.Default; - tlc.Clear(); - foreach (var tieLineConfig in ConfigReader.ConfigObject.TieLines) - { - var newTL = tieLineConfig.GetTieLine(); - if (newTL != null) - tlc.Add(newTL); - } - } - - /// - /// Reads all rooms from config and adds them to DeviceManager - /// - public void LoadRooms() - { - foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) - { - var room = roomConfig.GetRoomObject(); - if (room != null) + //CotijaInterface.InitializeClient("http://192.168.1.105"); + + Debug.Console(0, "Starting Essentials load from configuration"); + ConfigReader.LoadConfig2(); + LoadDevices(); + LoadTieLines(); + LoadRooms(); + // FUSION - should go per room I believe. See CreateSystems in original Configuration.cs + // ??? + DeviceManager.ActivateAll(); + Debug.Console(0, "Essentials load complete\r" + + "-------------------------------------------------------------"); + } + catch (Exception e) + { + Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e); + } + return null; + }, null); + } + + public void EnablePortalSync(string s) + { + if (s.ToLower() == "enable") + { + CrestronConsole.ConsoleCommandResponse("Portal Sync features enabled"); + PortalSync = new PepperDashPortalSyncClient(); + } + } + + public void TearDown() + { + Debug.Console(0, "Tearing down existing system"); + DeviceManager.DeactivateAll(); + + TieLineCollection.Default.Clear(); + + foreach (var key in DeviceManager.GetDevices()) + DeviceManager.RemoveDevice(key); + + Debug.Console(0, "Tear down COMPLETE"); + } + + /// + /// Reads all devices from config and adds them to DeviceManager + /// + public void LoadDevices() + { + foreach (var devConf in ConfigReader.ConfigObject.Devices) + { + Debug.Console(0, "Creating device '{0}'", devConf.Key); + // Skip this to prevent unnecessary warnings + if (devConf.Key == "processor") + continue; + + // Try local factory first + var newDev = DeviceFactory.GetDevice(devConf); + + // Then associated library factories + if (newDev == null) + newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf); + if (newDev == null) + newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf); + if (newDev == null) + newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf); + + if (newDev != null) + DeviceManager.AddDevice(newDev); + else + Debug.Console(0, "WARNING: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key); + } + } + + /// + /// Helper method to load tie lines. This should run after devices have loaded + /// + public void LoadTieLines() + { + // Make this reusable by clearing the TieLineCollection + + var tlc = TieLineCollection.Default; + tlc.Clear(); + foreach (var tieLineConfig in ConfigReader.ConfigObject.TieLines) + { + var newTL = tieLineConfig.GetTieLine(); + if (newTL != null) + tlc.Add(newTL); + } + } + + /// + /// Reads all rooms from config and adds them to DeviceManager + /// + public void LoadRooms() + { + foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) + { + var room = roomConfig.GetRoomObject(); + if (room != null) { if (room is EssentialsHuddleSpaceRoom) { @@ -169,15 +169,15 @@ namespace PepperDash.Essentials { Debug.Console(1, "Room is NOT EssentialsHuddleSpaceRoom, attempting to add to DeviceManager w/o Fusion"); DeviceManager.AddDevice(room); - } - -#warning Add Fusion connector to room factory? - - } - else - Debug.Console(0, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key); - } - } - - } -} + } + +#warning Add Fusion connector to room factory? + + } + else + Debug.Console(0, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key); + } + } + + } +} diff --git a/Essentials/PepperDashEssentials/Fusion/FusionSystemController.cs b/Essentials/PepperDashEssentials/Fusion/FusionSystemController.cs index 28f7cf09..45030424 100644 --- a/Essentials/PepperDashEssentials/Fusion/FusionSystemController.cs +++ b/Essentials/PepperDashEssentials/Fusion/FusionSystemController.cs @@ -1,505 +1,505 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.Fusion; - -using PepperDash.Essentials.Core; - -using PepperDash.Core; -using PepperDash.Essentials; -using PepperDash.Essentials.Devices.Common; - - -namespace PepperDash.Essentials.Fusion -{ - public class EssentialsHuddleSpaceFusionSystemController : Device - { - FusionRoom FusionRoom; - EssentialsHuddleSpaceRoom Room; - Dictionary SourceToFeedbackSigs = - new Dictionary(); - - StatusMonitorCollection ErrorMessageRollUp; - +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.Fusion; + +using PepperDash.Essentials.Core; + +using PepperDash.Core; +using PepperDash.Essentials; +using PepperDash.Essentials.Devices.Common; + + +namespace PepperDash.Essentials.Fusion +{ + public class EssentialsHuddleSpaceFusionSystemController : Device + { + FusionRoom FusionRoom; + EssentialsHuddleSpaceRoom Room; + Dictionary SourceToFeedbackSigs = + new Dictionary(); + + StatusMonitorCollection ErrorMessageRollUp; + StringSigData SourceNameSig; - public EssentialsHuddleSpaceFusionSystemController(EssentialsHuddleSpaceRoom room, uint ipId) - : base(room.Key + "-fusion") - { - Room = room; - - CreateSymbolAndBasicSigs(ipId); - SetUpSources(); - SetUpCommunitcationMonitors(); - SetUpDisplay(); - SetUpError(); - - // test assets --- THESE ARE BOTH WIRED TO AssetUsage somewhere internally. - var ta1 = FusionRoom.CreateStaticAsset(1, "Test asset 1", "Awesome Asset", "Awesome123"); - ta1.AssetError.InputSig.StringValue = "This should be error"; - - - var ta2 = FusionRoom.CreateStaticAsset(2, "Test asset 2", "Awesome Asset", "Awesome1232"); - ta2.AssetUsage.InputSig.StringValue = "This should be usage"; - - // Make it so! - FusionRVI.GenerateFileForAllFusionDevices(); - } - - void CreateSymbolAndBasicSigs(uint ipId) - { - FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, "awesomeGuid-" + Room.Key); - FusionRoom.Register(); - - FusionRoom.FusionStateChange += new FusionStateEventHandler(FusionRoom_FusionStateChange); - - // Room to fusion room - Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); - SourceNameSig = FusionRoom.CreateOffsetStringSig(50, "Source - Name", eSigIoMask.InputSigOnly); - // Don't think we need to get current status of this as nothing should be alive yet. - Room.CurrentSingleSourceChange += new SourceInfoChangeHandler(Room_CurrentSourceInfoChange); - - - FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(Room.PowerOnToDefaultOrLastSource); - FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => Room.RunRouteAction("roomOff")); - // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); - FusionRoom.ErrorMessage.InputSig.StringValue = - "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;"; - - } - - void SetUpSources() - { - // Sources - var dict = ConfigReader.ConfigObject.GetSourceListForKey(Room.SourceListKey); - if (dict != null) - { - // NEW PROCESS: - // Make these lists and insert the fusion attributes by iterating these - var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls); - uint i = 1; - foreach (var kvp in setTopBoxes) - { - TryAddRouteActionSigs("Source - TV " + i, 115 + i, kvp.Key, kvp.Value.SourceDevice); - i++; - if (i > 5) // We only have five spots - break; - } - - var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls); - i = 1; - foreach (var kvp in discPlayers) - { - TryAddRouteActionSigs("Source - DVD " + i, 120 + i, kvp.Key, kvp.Value.SourceDevice); - i++; - if (i > 5) // We only have five spots - break; - } - - var laptops = dict.Where(d => d.Value.SourceDevice is Laptop); - i = 1; - foreach (var kvp in laptops) - { - TryAddRouteActionSigs("Source - Laptop " + i, 100 + i, kvp.Key, kvp.Value.SourceDevice); - i++; - if (i > 10) // We only have ten spots??? - break; - } - - // REMOVE THIS PROCESS: - //foreach (var kvp in dict) - //{ - // var src = kvp.Value; - // //var srcNum = src.Key; - // var pSrc = src.SourceDevice; - // if (pSrc == null) - // continue; - - // var keyNum = ExtractNumberFromKey(pSrc.Key); - // if (keyNum == -1) - // { - // Debug.Console(1, this, "WARNING: Cannot link source '{0}' to numbered Fusion attributes", pSrc.Key); - // continue; - // } - // string attrName = null; - // uint attrNum = Convert.ToUInt32(keyNum); - - // if (pSrc is ISetTopBoxControls) - // { - // attrName = "Source - TV " + keyNum; - // attrNum += 115; // TV starts at 116 - // } - // else if (pSrc is IDiscPlayerControls) - // { - // attrName = "Source - DVD " + keyNum; - // attrNum += 120; // DVD starts at 121 - // } - // //else if (pSrc is Pc) - // //{ - // // attrName = "Source - PC " + keyNum; - // // attrNum += 110; // PC starts at 111 - // //} - // else if (pSrc is Laptop) - // { - // attrName = "Source - Laptop " + keyNum; - // attrNum += 100; // Laptops start at 101 - // } - // //else if (pSrc is IVCR) - // //{ - // // attrName = "Source - VCR " + keyNum; - // // attrNum += 125; // VCRs start at 126 - // //} - - - // if (attrName == null) - // { - // Debug.Console(1, this, - // "Source '{0}' does not have corresponsing Fusion attribute type, skipping", - // src.SourceKey); - // continue; - // } - // Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", - // attrName, attrNum, pSrc.Key); - // try - // { - // var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig); - // // Need feedback when this source is selected - // // Event handler, added below, will compare source changes with this sig dict - // SourceToFeedbackSigs.Add(pSrc, sigD.InputSig); - - // // And respond to selection in Fusion - // sigD.OutputSig.SetSigFalseAction(() => Room.RunRouteAction(kvp.Key)); - // } - // catch (Exception) - // { - // Debug.Console(2, this, "Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING", attrNum, attrName, pSrc.Key); - // } - //} - } - else - { - Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", - Room.SourceListKey, Room.Key); - } - } - - void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc) - { - Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", - attrName, attrNum, pSrc.Key); - try - { - var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig); - // Need feedback when this source is selected - // Event handler, added below, will compare source changes with this sig dict - SourceToFeedbackSigs.Add(pSrc, sigD.InputSig); - - // And respond to selection in Fusion - sigD.OutputSig.SetSigFalseAction(() => Room.RunRouteAction(routeKey)); - } - catch (Exception) - { - Debug.Console(2, this, "Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING", attrNum, attrName, pSrc.Key); - } - } - - /// - /// - /// - void SetUpCommunitcationMonitors() - { - // Attach to all room's devices with monitors. - //foreach (var dev in DeviceManager.Devices) - foreach (var dev in DeviceManager.GetDevices()) - { - if (!(dev is ICommunicationMonitor)) - continue; - - var keyNum = ExtractNumberFromKey(dev.Key); - if (keyNum == -1) - { - Debug.Console(1, this, "WARNING: Cannot link device '{0}' to numbered Fusion monitoring attributes", - dev.Key); - continue; - } - string attrName = null; - uint attrNum = Convert.ToUInt32(keyNum); - - //if (dev is SmartGraphicsTouchpanelControllerBase) - //{ - // if (attrNum > 10) - // continue; - // attrName = "Device Ok - Touch Panel " + attrNum; - // attrNum += 200; - //} - //// add xpanel here - - //else - if (dev is DisplayBase) - { - if (attrNum > 10) - continue; - attrName = "Device Ok - Display " + attrNum; - attrNum += 240; - } - //else if (dev is DvdDeviceBase) - //{ - // if (attrNum > 5) - // continue; - // attrName = "Device Ok - DVD " + attrNum; - // attrNum += 260; - //} - // add set top box - - // add Cresnet roll-up - - // add DM-devices roll-up - - if (attrName != null) - { - // Link comm status to sig and update - var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly); - var smd = dev as ICommunicationMonitor; - sigD.InputSig.BoolValue = smd.CommunicationMonitor.Status == MonitorStatus.IsOk; - smd.CommunicationMonitor.StatusChange += (o, a) => - { sigD.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; }; - Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", dev.Key, attrName); - } - } - } - - void SetUpDisplay() - { - var display = Room.DefaultDisplay as DisplayBase; - if (display == null) - { - Debug.Console(1, this, "Cannot link null display to Fusion"); - return; - } - - var dispPowerOnAction = new Action(b => { if (!b) display.PowerOn(); }); - var dispPowerOffAction = new Action(b => { if (!b) display.PowerOff(); }); - - // Display to fusion room sigs - FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction; - FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; - display.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig); - if (display is IDisplayUsage) - (display as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); - - // static assets --------------- testing - // Make a display asset - var dispAsset = FusionRoom.CreateStaticAsset(3, display.Name, "Display", "awesomeDisplayId" + Room.Key); - dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; - dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; - display.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig); - // NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig); - // Use extension methods - dispAsset.TrySetMakeModel(display); - dispAsset.TryLinkAssetErrorToCommunication(display); - } - - void SetUpError() - { - // Roll up ALL device errors - ErrorMessageRollUp = new StatusMonitorCollection(this); - foreach (var dev in DeviceManager.GetDevices()) - { - var md = dev as ICommunicationMonitor; - if (md != null) - { - ErrorMessageRollUp.AddMonitor(md.CommunicationMonitor); - Debug.Console(2, this, "Adding '{0}' to room's overall error monitor", md.CommunicationMonitor.Parent.Key); - } - } - ErrorMessageRollUp.Start(); - FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message; - ErrorMessageRollUp.StatusChange += (o, a) => - { - FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message; - }; - - } - - - - - /// - /// Helper to get the number from the end of a device's key string - /// - /// -1 if no number matched - int ExtractNumberFromKey(string key) - { - var capture = System.Text.RegularExpressions.Regex.Match(key, @"\D+(\d+)"); - if (!capture.Success) - return -1; - else return Convert.ToInt32(capture.Groups[1].Value); - } - - /// - /// Event handler for when room source changes - /// - void Room_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) - { - // Handle null. Nothing to do when switching from or to null - if (info == null || info.SourceDevice == null) - return; - - var dev = info.SourceDevice; - if (type == ChangeType.WillChange) - { - if (SourceToFeedbackSigs.ContainsKey(dev)) - SourceToFeedbackSigs[dev].BoolValue = false; - } - else - { - if (SourceToFeedbackSigs.ContainsKey(dev)) - SourceToFeedbackSigs[dev].BoolValue = true; - var name = (room == null ? "" : room.Name); - SourceNameSig.InputSig.StringValue = name; - } - } - - void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args) - { - - // The sig/UO method: Need separate handlers for fixed and user sigs, all flavors, - // even though they all contain sigs. - - var sigData = (args.UserConfiguredSigDetail as BooleanSigDataFixedName); - if (sigData != null) - { - var outSig = sigData.OutputSig; - if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.BoolValue); - else if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.UShortValue); - else if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.StringValue); - return; - } - - var attrData = (args.UserConfiguredSigDetail as BooleanSigData); - if (attrData != null) - { - var outSig = attrData.OutputSig; - if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.BoolValue); - else if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.UShortValue); - else if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.StringValue); - return; - } - - } - } - - - public static class FusionRoomExtensions - { - /// - /// Creates and returns a fusion attribute. The join number will match the established Simpl - /// standard of 50+, and will generate a 50+ join in the RVI. It calls - /// FusionRoom.AddSig with join number - 49 - /// - /// The new attribute - public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) - { - if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); - number -= 49; - fr.AddSig(eSigType.Bool, number, name, mask); - return fr.UserDefinedBooleanSigDetails[number]; - } - - /// - /// Creates and returns a fusion attribute. The join number will match the established Simpl - /// standard of 50+, and will generate a 50+ join in the RVI. It calls - /// FusionRoom.AddSig with join number - 49 - /// - /// The new attribute - public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) - { - if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); - number -= 49; - fr.AddSig(eSigType.UShort, number, name, mask); - return fr.UserDefinedUShortSigDetails[number]; - } - - /// - /// Creates and returns a fusion attribute. The join number will match the established Simpl - /// standard of 50+, and will generate a 50+ join in the RVI. It calls - /// FusionRoom.AddSig with join number - 49 - /// - /// The new attribute - public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) - { - if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); - number -= 49; - fr.AddSig(eSigType.String, number, name, mask); - return fr.UserDefinedStringSigDetails[number]; - } - - /// - /// Creates and returns a static asset - /// - /// the new asset - public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type, string instanceId) - { - fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId); - return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset; - } - } - - //************************************************************************************************ - /// - /// Extensions to enhance Fusion room, asset and signal creation. - /// - public static class FusionStaticAssetExtensions - { - /// - /// Tries to set a Fusion asset with the make and model of a device. - /// If the provided Device is IMakeModel, will set the corresponding parameters on the fusion static asset. - /// Otherwise, does nothing. - /// - public static void TrySetMakeModel(this FusionStaticAsset asset, Device device) - { - var mm = device as IMakeModel; - if (mm != null) - { - asset.ParamMake.Value = mm.DeviceMake; - asset.ParamModel.Value = mm.DeviceModel; - } - } - - /// - /// Tries to attach the AssetError input on a Fusion asset to a Device's - /// CommunicationMonitor.StatusChange event. Does nothing if the device is not - /// IStatusMonitor - /// - /// - /// - public static void TryLinkAssetErrorToCommunication(this FusionStaticAsset asset, Device device) - { - if (device is ICommunicationMonitor) - { - var monitor = (device as ICommunicationMonitor).CommunicationMonitor; - monitor.StatusChange += (o, a) => - { - // Link connected and error inputs on asset - asset.Connected.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; - asset.AssetError.InputSig.StringValue = a.Status.ToString(); - }; - // set current value - asset.Connected.InputSig.BoolValue = monitor.Status == MonitorStatus.IsOk; - asset.AssetError.InputSig.StringValue = monitor.Status.ToString(); - } - } - } - + public EssentialsHuddleSpaceFusionSystemController(EssentialsHuddleSpaceRoom room, uint ipId) + : base(room.Key + "-fusion") + { + Room = room; + + CreateSymbolAndBasicSigs(ipId); + SetUpSources(); + SetUpCommunitcationMonitors(); + SetUpDisplay(); + SetUpError(); + + // test assets --- THESE ARE BOTH WIRED TO AssetUsage somewhere internally. + var ta1 = FusionRoom.CreateStaticAsset(1, "Test asset 1", "Awesome Asset", "Awesome123"); + ta1.AssetError.InputSig.StringValue = "This should be error"; + + + var ta2 = FusionRoom.CreateStaticAsset(2, "Test asset 2", "Awesome Asset", "Awesome1232"); + ta2.AssetUsage.InputSig.StringValue = "This should be usage"; + + // Make it so! + FusionRVI.GenerateFileForAllFusionDevices(); + } + + void CreateSymbolAndBasicSigs(uint ipId) + { + FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, "awesomeGuid-" + Room.Key); + FusionRoom.Register(); + + FusionRoom.FusionStateChange += new FusionStateEventHandler(FusionRoom_FusionStateChange); + + // Room to fusion room + Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); + SourceNameSig = FusionRoom.CreateOffsetStringSig(50, "Source - Name", eSigIoMask.InputSigOnly); + // Don't think we need to get current status of this as nothing should be alive yet. + Room.CurrentSingleSourceChange += new SourceInfoChangeHandler(Room_CurrentSourceInfoChange); + + + FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(Room.PowerOnToDefaultOrLastSource); + FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => Room.RunRouteAction("roomOff")); + // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); + FusionRoom.ErrorMessage.InputSig.StringValue = + "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;"; + + } + + void SetUpSources() + { + // Sources + var dict = ConfigReader.ConfigObject.GetSourceListForKey(Room.SourceListKey); + if (dict != null) + { + // NEW PROCESS: + // Make these lists and insert the fusion attributes by iterating these + var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls); + uint i = 1; + foreach (var kvp in setTopBoxes) + { + TryAddRouteActionSigs("Source - TV " + i, 115 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 5) // We only have five spots + break; + } + + var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls); + i = 1; + foreach (var kvp in discPlayers) + { + TryAddRouteActionSigs("Source - DVD " + i, 120 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 5) // We only have five spots + break; + } + + var laptops = dict.Where(d => d.Value.SourceDevice is Laptop); + i = 1; + foreach (var kvp in laptops) + { + TryAddRouteActionSigs("Source - Laptop " + i, 100 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 10) // We only have ten spots??? + break; + } + + // REMOVE THIS PROCESS: + //foreach (var kvp in dict) + //{ + // var src = kvp.Value; + // //var srcNum = src.Key; + // var pSrc = src.SourceDevice; + // if (pSrc == null) + // continue; + + // var keyNum = ExtractNumberFromKey(pSrc.Key); + // if (keyNum == -1) + // { + // Debug.Console(1, this, "WARNING: Cannot link source '{0}' to numbered Fusion attributes", pSrc.Key); + // continue; + // } + // string attrName = null; + // uint attrNum = Convert.ToUInt32(keyNum); + + // if (pSrc is ISetTopBoxControls) + // { + // attrName = "Source - TV " + keyNum; + // attrNum += 115; // TV starts at 116 + // } + // else if (pSrc is IDiscPlayerControls) + // { + // attrName = "Source - DVD " + keyNum; + // attrNum += 120; // DVD starts at 121 + // } + // //else if (pSrc is Pc) + // //{ + // // attrName = "Source - PC " + keyNum; + // // attrNum += 110; // PC starts at 111 + // //} + // else if (pSrc is Laptop) + // { + // attrName = "Source - Laptop " + keyNum; + // attrNum += 100; // Laptops start at 101 + // } + // //else if (pSrc is IVCR) + // //{ + // // attrName = "Source - VCR " + keyNum; + // // attrNum += 125; // VCRs start at 126 + // //} + + + // if (attrName == null) + // { + // Debug.Console(1, this, + // "Source '{0}' does not have corresponsing Fusion attribute type, skipping", + // src.SourceKey); + // continue; + // } + // Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", + // attrName, attrNum, pSrc.Key); + // try + // { + // var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig); + // // Need feedback when this source is selected + // // Event handler, added below, will compare source changes with this sig dict + // SourceToFeedbackSigs.Add(pSrc, sigD.InputSig); + + // // And respond to selection in Fusion + // sigD.OutputSig.SetSigFalseAction(() => Room.RunRouteAction(kvp.Key)); + // } + // catch (Exception) + // { + // Debug.Console(2, this, "Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING", attrNum, attrName, pSrc.Key); + // } + //} + } + else + { + Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", + Room.SourceListKey, Room.Key); + } + } + + void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc) + { + Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", + attrName, attrNum, pSrc.Key); + try + { + var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig); + // Need feedback when this source is selected + // Event handler, added below, will compare source changes with this sig dict + SourceToFeedbackSigs.Add(pSrc, sigD.InputSig); + + // And respond to selection in Fusion + sigD.OutputSig.SetSigFalseAction(() => Room.RunRouteAction(routeKey)); + } + catch (Exception) + { + Debug.Console(2, this, "Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING", attrNum, attrName, pSrc.Key); + } + } + + /// + /// + /// + void SetUpCommunitcationMonitors() + { + // Attach to all room's devices with monitors. + //foreach (var dev in DeviceManager.Devices) + foreach (var dev in DeviceManager.GetDevices()) + { + if (!(dev is ICommunicationMonitor)) + continue; + + var keyNum = ExtractNumberFromKey(dev.Key); + if (keyNum == -1) + { + Debug.Console(1, this, "WARNING: Cannot link device '{0}' to numbered Fusion monitoring attributes", + dev.Key); + continue; + } + string attrName = null; + uint attrNum = Convert.ToUInt32(keyNum); + + //if (dev is SmartGraphicsTouchpanelControllerBase) + //{ + // if (attrNum > 10) + // continue; + // attrName = "Device Ok - Touch Panel " + attrNum; + // attrNum += 200; + //} + //// add xpanel here + + //else + if (dev is DisplayBase) + { + if (attrNum > 10) + continue; + attrName = "Device Ok - Display " + attrNum; + attrNum += 240; + } + //else if (dev is DvdDeviceBase) + //{ + // if (attrNum > 5) + // continue; + // attrName = "Device Ok - DVD " + attrNum; + // attrNum += 260; + //} + // add set top box + + // add Cresnet roll-up + + // add DM-devices roll-up + + if (attrName != null) + { + // Link comm status to sig and update + var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly); + var smd = dev as ICommunicationMonitor; + sigD.InputSig.BoolValue = smd.CommunicationMonitor.Status == MonitorStatus.IsOk; + smd.CommunicationMonitor.StatusChange += (o, a) => + { sigD.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; }; + Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", dev.Key, attrName); + } + } + } + + void SetUpDisplay() + { + var display = Room.DefaultDisplay as DisplayBase; + if (display == null) + { + Debug.Console(1, this, "Cannot link null display to Fusion"); + return; + } + + var dispPowerOnAction = new Action(b => { if (!b) display.PowerOn(); }); + var dispPowerOffAction = new Action(b => { if (!b) display.PowerOff(); }); + + // Display to fusion room sigs + FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction; + FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; + display.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig); + if (display is IDisplayUsage) + (display as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); + + // static assets --------------- testing + // Make a display asset + var dispAsset = FusionRoom.CreateStaticAsset(3, display.Name, "Display", "awesomeDisplayId" + Room.Key); + dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; + dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; + display.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig); + // NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig); + // Use extension methods + dispAsset.TrySetMakeModel(display); + dispAsset.TryLinkAssetErrorToCommunication(display); + } + + void SetUpError() + { + // Roll up ALL device errors + ErrorMessageRollUp = new StatusMonitorCollection(this); + foreach (var dev in DeviceManager.GetDevices()) + { + var md = dev as ICommunicationMonitor; + if (md != null) + { + ErrorMessageRollUp.AddMonitor(md.CommunicationMonitor); + Debug.Console(2, this, "Adding '{0}' to room's overall error monitor", md.CommunicationMonitor.Parent.Key); + } + } + ErrorMessageRollUp.Start(); + FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message; + ErrorMessageRollUp.StatusChange += (o, a) => + { + FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message; + }; + + } + + + + + /// + /// Helper to get the number from the end of a device's key string + /// + /// -1 if no number matched + int ExtractNumberFromKey(string key) + { + var capture = System.Text.RegularExpressions.Regex.Match(key, @"\D+(\d+)"); + if (!capture.Success) + return -1; + else return Convert.ToInt32(capture.Groups[1].Value); + } + + /// + /// Event handler for when room source changes + /// + void Room_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) + { + // Handle null. Nothing to do when switching from or to null + if (info == null || info.SourceDevice == null) + return; + + var dev = info.SourceDevice; + if (type == ChangeType.WillChange) + { + if (SourceToFeedbackSigs.ContainsKey(dev)) + SourceToFeedbackSigs[dev].BoolValue = false; + } + else + { + if (SourceToFeedbackSigs.ContainsKey(dev)) + SourceToFeedbackSigs[dev].BoolValue = true; + var name = (room == null ? "" : room.Name); + SourceNameSig.InputSig.StringValue = name; + } + } + + void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args) + { + + // The sig/UO method: Need separate handlers for fixed and user sigs, all flavors, + // even though they all contain sigs. + + var sigData = (args.UserConfiguredSigDetail as BooleanSigDataFixedName); + if (sigData != null) + { + var outSig = sigData.OutputSig; + if (outSig.UserObject is Action) + (outSig.UserObject as Action).Invoke(outSig.BoolValue); + else if (outSig.UserObject is Action) + (outSig.UserObject as Action).Invoke(outSig.UShortValue); + else if (outSig.UserObject is Action) + (outSig.UserObject as Action).Invoke(outSig.StringValue); + return; + } + + var attrData = (args.UserConfiguredSigDetail as BooleanSigData); + if (attrData != null) + { + var outSig = attrData.OutputSig; + if (outSig.UserObject is Action) + (outSig.UserObject as Action).Invoke(outSig.BoolValue); + else if (outSig.UserObject is Action) + (outSig.UserObject as Action).Invoke(outSig.UShortValue); + else if (outSig.UserObject is Action) + (outSig.UserObject as Action).Invoke(outSig.StringValue); + return; + } + + } + } + + + public static class FusionRoomExtensions + { + /// + /// Creates and returns a fusion attribute. The join number will match the established Simpl + /// standard of 50+, and will generate a 50+ join in the RVI. It calls + /// FusionRoom.AddSig with join number - 49 + /// + /// The new attribute + public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) + { + if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); + number -= 49; + fr.AddSig(eSigType.Bool, number, name, mask); + return fr.UserDefinedBooleanSigDetails[number]; + } + + /// + /// Creates and returns a fusion attribute. The join number will match the established Simpl + /// standard of 50+, and will generate a 50+ join in the RVI. It calls + /// FusionRoom.AddSig with join number - 49 + /// + /// The new attribute + public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) + { + if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); + number -= 49; + fr.AddSig(eSigType.UShort, number, name, mask); + return fr.UserDefinedUShortSigDetails[number]; + } + + /// + /// Creates and returns a fusion attribute. The join number will match the established Simpl + /// standard of 50+, and will generate a 50+ join in the RVI. It calls + /// FusionRoom.AddSig with join number - 49 + /// + /// The new attribute + public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) + { + if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); + number -= 49; + fr.AddSig(eSigType.String, number, name, mask); + return fr.UserDefinedStringSigDetails[number]; + } + + /// + /// Creates and returns a static asset + /// + /// the new asset + public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type, string instanceId) + { + fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId); + return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset; + } + } + + //************************************************************************************************ + /// + /// Extensions to enhance Fusion room, asset and signal creation. + /// + public static class FusionStaticAssetExtensions + { + /// + /// Tries to set a Fusion asset with the make and model of a device. + /// If the provided Device is IMakeModel, will set the corresponding parameters on the fusion static asset. + /// Otherwise, does nothing. + /// + public static void TrySetMakeModel(this FusionStaticAsset asset, Device device) + { + var mm = device as IMakeModel; + if (mm != null) + { + asset.ParamMake.Value = mm.DeviceMake; + asset.ParamModel.Value = mm.DeviceModel; + } + } + + /// + /// Tries to attach the AssetError input on a Fusion asset to a Device's + /// CommunicationMonitor.StatusChange event. Does nothing if the device is not + /// IStatusMonitor + /// + /// + /// + public static void TryLinkAssetErrorToCommunication(this FusionStaticAsset asset, Device device) + { + if (device is ICommunicationMonitor) + { + var monitor = (device as ICommunicationMonitor).CommunicationMonitor; + monitor.StatusChange += (o, a) => + { + // Link connected and error inputs on asset + asset.Connected.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; + asset.AssetError.InputSig.StringValue = a.Status.ToString(); + }; + // set current value + asset.Connected.InputSig.BoolValue = monitor.Status == MonitorStatus.IsOk; + asset.AssetError.InputSig.StringValue = monitor.Status.ToString(); + } + } + } + } \ No newline at end of file diff --git a/Essentials/PepperDashEssentials/PepperDashEssentials.projectinfo b/Essentials/PepperDashEssentials/PepperDashEssentials.projectinfo index 51aeea25..cfae0787 100644 Binary files a/Essentials/PepperDashEssentials/PepperDashEssentials.projectinfo and b/Essentials/PepperDashEssentials/PepperDashEssentials.projectinfo differ