From ca7a3d7071cc7c3e4f3455ff31e2f242693af546 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 28 Apr 2017 11:17:20 -0600 Subject: [PATCH] Fusion now working for EssentialsHuddleSpaceRoom types --- .../PepperDash_Essentials_Core.projectinfo | Bin 1281 -> 1276 bytes .../Essentials_DM/Essentials_DM.projectinfo | Bin 1142 -> 1137 bytes .../Essentials Devices Common.projectinfo | Bin 1163 -> 1158 bytes .../PepperDashEssentials/ControlSystem.cs | 340 +++--- .../Fusion/FusionSystemController.cs | 1004 ++++++++--------- .../PepperDashEssentials.projectinfo | Bin 1865 -> 1860 bytes 6 files changed, 672 insertions(+), 672 deletions(-) diff --git a/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo b/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo index f1ca8e713eca08bf721f136af25f99052303583e..ddebd653587248334c9f7a6d15cbd684b15ac6c1 100644 GIT binary patch delta 1158 zcmV;11bO>`3j7I>g@0myo6>hL^VKS^pJvVc_dji#eAyQC-S2-=)j7R1yQx7=4d}=h5E7@x6lw2fO$8w|72$w6jC)=G5-w(eL~Fez&UM z7R!tDX;J6XwyKM~`F($1*Wd5^`@a71-}m>;ZKuEQ@9Pjqfq#JC*nRaRYv`LvvGl+0 z;y#|P${!Fag(b$zy83Ct;%s?dJuAw5nJw}k0-75zTnR!2Aw-CtHPn53ZP9&w-L(1Q zg;iFGNZ?{S%j@Q&M@E$PKKdo2kG?3D#bUj9R@95D ztj>RuS`dvOXycuohxGrwhXnk~b-P-(FSGV%pWUgqFS2EEo;R&S^&WkCBYzl5e32E) zWBO__DX$%fefq|mwGCiqWl3!VO3;6Md%F)oiVnfLlz;j*K}2u6I|nQ(_Nfu~uP?@#vk?mx`3 z^G|ml?tk2Wc)pY6_xAT6+?$-w_Iv`r2XuMo_I=!LW*)r<20!E}>`&46M<2b)8>R#Q z`AbG-(muW2qhYxli-rwEd$@5Ro zcPIP#WP1PJ`Tab5aEp1`*iA5Zx9IG{=58Y@|1X};gImq#t9((ld1nH%^Sw{=oyp$4 zo&CLs`KJ%}rn7tZck=0{_ofeb9!&CEOkfB%n6Xg^x7~Adti|1r_C!7>- zsGc)oD7G`(ojjZ!Ja};L{=4cK5_ZUOwg=ViF-|2I$2y`c$u{S(i>otMk1 z+@HFgkTaBy$7KY4I}Z}-9do!#kV@?cLd!> z*q&x>HlAgzo1KHboyn)W)BS_#LAE!g!5-{Ay#FB2XTpF delta 1164 zcmV;71atfR34scbg@5wVqqbhtFH`#JWxiVF_0z1G|Nf^^ z)PR1R%a05CvA47PV0&kOd+))Uy}d{GcOLCM9N#;5aIkxSe|zWCM>{*zZcgn^9{s+* z?{};EZLz#apB8mKZL7M-o8R~Mb^ZOmzwhfG|9yYo+;;l={(rs>ffNY%jonvIvWC8y z6iff>F7D&$s{8?=Qdp|ItgD|UEY6na)w80^m)Ro!A)vVd!<8UZ5JH6LSwr2o*JkQo zUpH;Ocp*q`oFW?6MV&3qW^b~KTee-~wM^*oY*w^IwaiM8MLs*J7AvC9?91gXXWP8+ zL!|00C;xOY$$w|Bt93oikL&5YxXdj#oK&mpH`TMMoaJ@%(IX>BdmsIh(MMkt%VM!! zJS*zORaWOeNiB#*5VP^l&O`eD-a`WZ<+@$1+m~7Uv(N3++ZWlgIM18bp?Z%#y^%i* zCBDdt;K>F#VlyZ7MJ?B3+wr}y_i-N~lZQs(MbBT~ZO-0*od&B`CjG~LXXLdK{0Dqqg> z<&?Vq=+XDgY}^lL9}IeBoaIXP|TdA-bAGGB}JvVWLnFoaDwPxn5}KmGLH{=)~m5AW~p z@8tQX=ev{rd@{X%@BDtAJ-Ed@ZR{qPyIXYjVRN?;mH!vd=fSP!^Hsj6+PpJ?+4
Bs!~D~Sd(+vy`#bsc(|gm0I}axLEhaF88_d`(pnuqmg?<0Oc#0n0YKp!( z3x8*4=iuSJ-MwsQI@y`*-@o@@=fU2L7=G{Ge*R!L-?`1~SdhWQ+yd~2O^ogK|HX5% zyAw`|H&o9VF%;XG?M@!f4jw$XcmLtR{qz0vNxnaw-M>HGo7~@LKR@Q2d4R$RxEb6n zCm`P0|C`Ca80k?p8%L&-f|lR7 zojusSe}D4u;lY0X>4W`)gGt~<-v(?jFSh{x-t#it_5YhE=-$u-z5a>k-_A?wWq)9P z&UdEwcka(-`E+)WJvg{G+n+qRzqk9~{?6`nGI=mCKZ8(%>A3~$_nw}?p8wxBJDm^g zTy+u!ZfsApHXF~f*3Hhr-p=IH-Rb_p^dQ@t(qIqv9^QYD=QCpWdk-G`FrxejdcWlR ezvP#2{-QWnzn8|jE?XJ){{ud5iuO_ML%f@%a05CvA47PV0&kO zd+))Uy}d{GcOKn)Fn;jh(@*a|e7L>y>7$(;YB#5LCy##L-}k#!{kB+Mq)&@FpSD$9 z0*-4URUdS znjhEGd2yLrT7R8XtLrz_v#Olsb@S09!^nFd{gTl~Ulhw?v0gkY>cv%7=RZj;h!SA) z@y^ae`v2ZT0{-Q?U9H=fS^KlXhSb3q*|Ip#o7Q1>k3QAub#Q?jFqc^64bcCp-5aYKD^IBKS@#|u-DqqjDdPM>_ewtqv)BN>%wW{h?0V*}8S(fil_V?~T%(C-OcOUND ze|Wx=<$w3~_aEGwoX_@rYQ6__dFS?h+-4#ky+{8)`!m*`lkbl{dX+akaQ^d`jLa;3 zdb?RNbFE~X%+Bv;)AQ_LXF9z%nH)Sg-`kxLyFc9B-8-1<&Tca`24pZFw*dS>^IIhV$S=^hJKvR?DV3?^uF|)18OY`?GsHvn-#@X6FYF?@#Z2 zntx3v=h-yhnceqiU<0&(_P2m}E81`9@Bdv?-`yD^`>XuCgo|A*&z5aog8(7@^Lyv# z2l;F=$qx3X)7gXF`}ZdgA0F)IpFY?>IG6;M_%>jJiMR#u_ne5~j{jdaBfCR0^7<#9 ze>*P;i-8F_-hPngbYFr=HnKy-*Y|& z`~82#baXzjle0H8IZv}T8_%-VO~=9B&g9eG>Hfj=AR~u=njh>vB=Ti@f=Lf8Uq+YL(Ydvu6JL{=Tn&{P+ERbKB+b`}?}?(|@O5_<#QX_;XS$JD-iG ztMUibVPQx3vaWub`Z`;lSI>$vUuKK^X9t-OkCk*=P`8B6Swo$)*M``yubVbsybx5n z6eff(>TGc~dy`!Zf4#_SnS$fltZ0jBnUxr#e0EYTRy5Yxm&;quk9px|mqNqSb-I}3 zv)9$Sp618(bbnr4=63#0s@3(I>RDCJ^1AuxkzwP#kABJMqc4hOu~;vj74_mOtMi|v z7DNd!`FLmNA^m^vAp!q#-LBT{%dGub;X>-*i)>k(=S}OdyGNhu^g6h|e{|?yWX1BB zzF17kYX@MTzVRkw5Xh`7sbw&5`tRPud%F)l>d~i5n162*Jo@a@Pj?Syd--&d=aZfL z5Aw;u?%p)po!-Bg%IN z-!p{29}@ngrg^Qa<@j~6Se38mS-m0w96!x3i)sFPy;@aus{oan(=5yPC;NN%A7P0nX~J~iJ1y1aAyK5jD+kKUvIpZyu@&&l^kAHB*O9ytH` zOGajvKE2&6nYmW7O=jo!v*~$uurrhOKRmd9zJET+_ouV__osW4`}=Hz zVmihH6cGFt;BH0mcvt`LBJ;s*OhKRG`@1^_JG=MK&u90ED|cu6*}Vs!X7?udKE1#H z=}tDiS*s5b{}zznm-z8s|KBwa55swIBKjh~YO7^aop&t3!|Be$>HXQgomrO8X0!8y zhky5{_dd<0lk;qv@67J|Gq3?#K>J(3ycO*?^!NWRs_*U$k^NPEUc$q!mS@X0uR(y2 z{`tN0^MiagnPdn1)9LKN?*03dhYt_-^G_e_9~?{qOMDx!!9?5w_qaDQ+2!Tp`x>16U?U_u6=2J>+X z*zY+XgZ=)$Vmdk>*vZ)&nw+Oun~i5#>!#yiZ)fu9?sWfPdXSOBKg|#J9+LZ?&xoP# tJ$P^n3-LjIe+0E(^8H`(OE{V-&WmXVQJ^ud%T|W`{{RIZ%Amp!002GYP}cwe 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 0093d01b53285c04c1f2f6af29f917ab2558279f..42dae6e2540fc6a5906e0ea4519a77df457d4213 100644 GIT binary patch delta 358 zcmV-s0h#`b35E%fg@0myo6>iuO_ML%f<8!}=9k4ZZ_<-$v8a~x&Mf%;_t)=#{}cKu zr?2S8x%{}GAA38y54LyqxAz{r+1q<`f9KJ?{qfGddk-EQ>~HUU`eC>Xlr)^aidGq`JzAy9DDzBer&HVTMeP93h?|=LI=C8ktzAyrs+7b? z7cT_gO*2X(yr{Fq+3Zbr5i|`ZS6eOeTBi4SHY?hqT4p6kBcBn-713z+*>6>%q@ves@3(I>RDCJ^1AuxkrA!EkABJMqc4hOu~;vj z74_mOtMi|v7DO!w-gsx{A^m^vAp!q#-LBT{%dGvOO0&}e=K%p-le+`R2;C4>nNAV_ E0FpD$EC2ui delta 344 zcmV-e0jK_k35yAkg@5wVqqbhtFH`#Jv}y8XThKS@)BLiS=1qE1Ef&?1UYP~o|Ni>@ z?|(vH<@6Q(IF}z6^kZ*l_rdng{`TI3H+y@J?(aOhw?E#wckjW2gZ=HDPao~>bJ%6B7Iua`LwO-B5!`*-}hy{TIKcAteOA5zkl!RAOC%S-`w{6`~JRz zSZ@4kQf&HuJYAJPAfyUQn3r|+(}d62^1OOhl=(7S - /// 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 51aeea255bbefd6ecd9ccc23cf4868c12d9d46d7..cfae0787f28f3000a8f769e64214ac4eb82f3865 100644 GIT binary patch delta 1602 zcmV-I2EF;o4#WhL^VKS^pJvVcv}y8XThLe3d^Y@5PG8ZFbNO*WKlXNZ zA8haJZ|^;Lv$yx?{?4QQd*i*m2lwtj+~3~$^wG`^wVPABlSjYr@B7`Vep@Ur(x*k8 zPur?4^5*ybeO*t#@9+Ei$A917H@E%$zQ3>Q+i&N8Iw_X%uYbnV)eora!VdUlUHvrm zdbT{To)u-j%oh329$Hb1R)Rr67!YP>4fWSvTl`*MH*LOnA!rSdpT=-eXN$Aho9yDo zR*SrrX*!~*!Sr}=R`ofnt6 zrQu1nx_(nVtAEN_UN;{-GBU9D(JvW&^hL2O7VE{cqF!8Ob^epof@lH>8Sm^or2p?d zB;a4J+ts>#nYBM_JWHK?ku8h!ylEYV_vq6NQ?DccA}f~1^xeMVG&us8j5fA9QZ{(tH0!SoF&dw`w!1|vi#ou{)2my z^VyzH!+-aHF7MpFj~nLT(R+0L!3MdrGo9X>Ob#BL@9oa=$-%?j-Mxd!?(8-*V?YMeaSOm-cREae|L>cF2e+Do({`TM z%e*DqvRE&RX$C80L{Q0h@6-I#Pw(wNe6aiQ{(tWNPM&{yzB}2^C)4})&hO{hgImnY z#%_YSxHg%?>BCR& zW#@ad^V?{+0BkTnw*dY%=O^g%|9$iE@K*EjdDiAv*>y*P9_;P!<$Jq(S$6MW|K8r- zL4S6C_HdU7`RT#l!}Eje7BkWT9L&irz<Gb;lzFFDbxz)71$`@6ecV>kc_S1Z4 zvUhK1e~oZO8qco%{L0gPl+J&ObdM6a47|@?dA5W)G*?y@%6Jcl=4X31lz{w*Y+8 zB;3^B{|hJKUN{L3=t))QFUf_^%GcM+X*dT5yZ7@?cMhhLgY4j7=U|pic0YY^aDVT? z^!(uAWcPkxEpC7qOu;SS-ZTX_boc+l85j)Be}9aiqk(p2yOW2rg9pgF9Na(OKcD3L z)7ky|)4j?4{hfgMeDIPBi-#NEzeIH|8!Ez-iP`Ssbd z&Fk}Q+7XA@Z2!T--R$7g*{A29KA6p>_jVpm_eoFZd;3!gi~WhX9pGR-Zhry(run#C zum3NcmQFbBjbq)k)#A8q>teDdw|Zb|h)|RL+5YtY?!(Ea_wQ%t4|jHUKh0;;Y>!f} zlZOLSa|7^TdT!ChdrZ#_J^#OOiaHUt8_T!zlE4p4Oop5|>6e_GO3JrVmgv(5I|q~e z!KeHC_h-{td}87t!vOAPz<;-&j(C6n@0*0ZPCV^K@FKrzDPLBdck<~Er=&#g&+hHa zh+wlB`I7gi_dd<06O40bc0W%49<+`m+z9jbr0;e0|3a#FBIYp4%-`jX+~*WNipWq$Veb{|k;JInLXR>!~ubiM_!+tbFmMo{ri)L4-fY9Pao_b987|2Y6vzCldJ}n2t&Zv4~ioI02VZ_ A9RL6T delta 1607 zcmV-N2Dtge4#^IXg@5wVqqbhtFH`#JWxiVF_0z1GpEgatYzt~bt!Kku<@6Q(IF}z6 z^kZ*l_rdng{`TI3H+y@J?(aO>zc=37dvNdm!~N}@Pao~>bJ%6 zB7Iua`LwO-B5!`*-`Dl@`~JSKfBg6TeRJF2@B90@zWsLor+<@T8UJcLUHyQ%F6_u( z*40l_uV>5i>RD0d%WRSV?4cFKXeAgFgaKi8)=+=#wV99C*G-!*UICsUoLMsh318yebU`Dqo<2WK6_oQ>uG*m zPv^yDZm0O9T7O-?sh(BkEU%l79vKPP`{5Fh? zCbRSV+4MX+*qKi6O(q8q&i8g_`Q+f??(W{fWOsI(nK2-P>9_^puR9&4zyJ5m!Gl}P z!D&0s>t)`OZCR|B#WaJJG9swtyZ34S>8JPhAAdgBeRzL&e<#mBJ>Q+|=acFEd*}D_ z?7=POWn(wNT-~CxuQ^v6arl4V{2knC{+_L2PQv-xo92^G_wQ%3`&qX0@ZkKx!E}G} z>Ga{J_pBF4|ll&I562c886+ypY1 zgj)c^OxkpXXWebFm?}8_QtVp+G=s!wskRClUqG7HAJY%{%n7GfA`_!)BE?c^M^Y-yPxK> zX|_kH*U7_ysks4oFg>^E;ytG4hMxalI7OWZ+l}Shc}d_0CMH8pob*dhP9^1ADNFR} zgPns({@~O7{rj`&EIu)DkbhwScQfGIPe;7J|MyM8UMHS*BY2TtwUjTb&O7<^hf`7_ z_hrjC{%a(|ez0(+S48GrJ$Be-Bzm5^jWfd(!v1`hOwSI}vjjW#;d4NA7b9 zpK=OXAAU;F>+E1}hcZ9=d%F)Pv7P04Xscsj0y^IU*zM`;`uKk#fipYNu*3RQeqLfh zxLOYAm;B!O`9VILOtORh>2&sB_x}CK!-og^`KJ%|4-O_lHnj^j29u`-l?e22nNo-& F002#NtIz-d