From 64b0e42c50db6c52ef1f62c168f42593f41772a3 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 8 Jun 2017 16:00:35 -0600 Subject: [PATCH] - Added support for Node server communication implementing GenericHttpSseClient --- .../PepperDash_Essentials_Core.projectinfo | Bin 1280 -> 1285 bytes .../Essentials_DM/Essentials_DM.projectinfo | Bin 1134 -> 1138 bytes .../Essentials Devices Common.projectinfo | Bin 1154 -> 1159 bytes .../Config/ConfigReader.cs | 286 +++++++++--------- .../Config/EssentialsConfig.cs | 84 +++-- .../Fusion/FusionSystemController.cs | 21 +- .../PepperDashEssentials.projectinfo | Bin 1862 -> 1865 bytes .../UI/CotijaInterfaceController.cs | 159 ++++++---- 8 files changed, 319 insertions(+), 231 deletions(-) diff --git a/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo b/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo index 6b5fb15e4646e0bc97649f53721b4a84042df00a..33a0466539677930ef71927ce856b90af56fb709 100644 GIT binary patch delta 1057 zcmV++1m63A3WW-gg@5wVqqbhtFH`#JWxiVF_0z1G|Nf^^ z)PR1R%a05CvA47PV0-7&?VW=+yZev!?>*Z6bo}tsd-r!A?9s=Mc6O-UoZ6i{`h9=j z?^gBOVtJ81E$V#QR&|j#zwhts`ulx<-`79>`~JSU?ezEkeSaMSDG=}*yRV*P4Sh2y zmj2gW+{e>Z`2#|wuvB?jS3gZyoGs6*XGNJWvqkw20W*VB1%nOkl+saDr-s%KR>%j@Q&M@Ep7oBe~bn2=AZoeLA~0+uePTKiJ#b-Fx`( z!DMzX-=EI*_V;)0Q%jkvTa8Ewe{;j<)if)ADARN^UkVwY=Bs=;%a>E?`lCnRGqV8# z_%c+}bl25#{JL1I%GdL(UXl2YpXQgvG=IHbt*W|JfJ)$LmgW1C{k?zt53}t2)7^(V z_aC0`Wcj`Q{Rj6Z=d(SZ!0!QF-no4rx0{(q?}5P&c?$be^!?FCukwcJz<>Udk(snl zZ#QXQgflgno!`%<=h?x|bb4!%x2M>35_YNkzv)jy+0U1osEdYPu^q6k{ zUpyxdZZ#*T?L4oSc}suhYq4Gy(+q~N3FqnFr}?L!-rIlpVE5tu-Tj?B|MYx!vY$_; z_wSwG&$9=&n5T{11ao(b&OU7JHlp(X;`uzd)qK9n7gd{gCNLwDlkZIS?(OXFJK(}t)^(`tFv%+b`Boi+uh4{ zrjwn?{{4Fob{_1_h~f9{?dK16^PStwjs+P^%q;+a*u>aw|6e>OyF1~ectiD^5vAC{ zWPf*haGvJ}pYBa|?|*u*dw=rj^n7}LFnzGIv;V0-6>&hp1l$6X-2*j$nFWsV257+q z+ydq;CtyR5|8Jg!y`fonm7kXgyQ}5dvdwGIBb<)>-ud}KKATLkgZ=4r_F(t^{mH|J z2mAS_5B3iZCV?A$8?eE=+yeM}&&zPv|8Jh4dqWfS`X`=$J1?o1f%!S#ncm;IKbz&# z*+KT;;NEP1^5Fj7?t}YqJG;}#bUv_i)kze%u|3V& zY&^?a&yeixOg`P6?jKAKvb`w{_F(Vf{ReqIBX+;{;K6jjki=+sYhrh38A0!teE*mH b63$-~=j!*;IM-z>!~TB&)6kAMM->17%`RX) delta 1052 zcmV+%1mpXK3V;fbg@0myo6>hL^VKS^pJvVc_dji#eAyQC-S2-=)j7R1yQx7=4d};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#BpaB^cXycuohxGrwhXnk~ zb-P-(FSGV%pWTzs0WE*K4<0fpIt1%d>e~d7K0BY@JKukJuzP=J|K9%O;m&z>Z+}0} zr=LE!x4(OTcAr|xT-|C!O8A=_KCh-(`9qneoB2}6_%vVT%UQmhQr90n`kt8$5WttA znx?z1mgCpOVpYDLXZ4E2clGa-Ya`51MZ+DhY4j%6A?j1~aXSbOt12UMNTLAvR=`r2@zj#g_ z+-gov+j(9u^Ok?i*J8aarWp)j6VB7UPxDVdy|@4H!S2KRyZbwN{^|MdWIvxw@83JW zpJxwlF;5%23Fht=oqgEcZA9h&#q)V^tNDDDFRC{0Okj4t_i4T}*}J#1zxOcz^x@ug zcJKZU*_?aRhdU1@`7I_egd5D*EueqcjD>ywzj%rs-fC!yzB&tMXXoJIz1_WRXFA!L z?BBolVCTW!j2M3J-hTdIH{ZF<>{yV&#M}b#hfR#__W#9mvbz&biZ@ix88H;wne9#< z&JG?txOe~I!Tt07^GUuxo!!4b-J9IsXFosYoOyu43Ah=P;R7{)2_54N(1HoL1>nIV0yp|LV1s$N1@QNtm*KAe-#kJ0h9>CsPdxv2UQ#au^K-s4y}xsRHp{28gY3b< zz1jZc!Tr762lsbxcBhlcgMs-Ogc?lGEnvU*^bGd=|GwGjd|>CQlPGXwdz!V`c$T$p zb`JJ-CZFz3_YbBA+1``}d$9NL{)0T95xd`e@L)P%NMba+HL*LijG*^RzW+;p3Fj}0 WbM<>^oa?fcVgEmn#>jR_6#xL^tXF;j diff --git a/Essentials DM/Essentials_DM/Essentials_DM.projectinfo b/Essentials DM/Essentials_DM/Essentials_DM.projectinfo index 483e19747b784033b8770e141455fe002e1d10f0..dbf3a423d0306338bed46ce1e6715331e698ef2e 100644 GIT binary patch delta 793 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 delta 962 zcmV;z13mnQ34#fbg@0myo6>iuO_ML%f<8!}=9k4ZZ_<-$v8a~x&Mf%;_t)=#{}cKu zr?2S8x%{}GAA38y54LyiZ|~iIv%C9fZ}-vu{&;_9Z}-!^?VSgYc6O-QoSL0H`h9=j z?^gBOVtJ81E$V#QR&|j#zwht+GGDFo`f1k8f8XEt^^gC)zkhFTJN|ut-$5idel;mJ zeLtSA${!F?g(b(!y83Ct=WKaiJuAw5nJw}kF2cjOt^~D$P$QJj8bYMKwuryJZrXhD zLh#)*p)|saI$NC0-eea+(_n73)grHDc8_PXqAjXrR)RG08G&38jb>jiZ#VU({m%_y zZ^sFzi%C9vT}rL%X?|Q!=f!1iDST3`uHRJ8s&bas%}0-nVC{YMOGY1kQ7ntadhx8N z7gt%G|0J~_VnOW2J39~Q|9cM!_?PQ;wQgT#?GIH5lhFY!f9}Dj_o0(IlqbTu zaz4#h`Er&or-Z~ukG^Ln<$gFRCpAraO)tGJ7OV30JgZkE*kghCdc9gzb*liC(9C(`#x?pMUUPCfuFm%>`&JB zM<2b)8>R^V`AbG-`aZqY^nISS`Biq^gfsVGZ+|b}+uh5udk6dX_Vy04`?H6;`Q+12 z5B46OA7rp?hQ4xiuuU8Jh>aDH}nX1kMzvx5f@?%jWQ zaQ}S&e3I`^XZP<<_a^uE*+AO)i31Ae;}+m&t|jpgNOI0_dd<0lk;qv z?}Ssc0a`FAw}5%ON!ifh|2L*%cV}omUghT{f{SW-wruknlnEy$zjuCqkk2NQ>|lR7 zojusSe}6(w*?#`%gZ+bpN#GdV25c}xw*daWGc?@u|3{{3cWA0!|HSie=Otk`FjIf$ zJJb6+_h++wIy=Z79Ne4jPafRg+kJ3|F52>&IfkZ z_J(HdY1U@rS=PFFI@sHpe7ZZ`KbRh5ds7-WIa2o@JC0M*&;HB1r!0Bn#LQUCw| diff --git a/Essentials/PepperDashEssentials/Config/ConfigReader.cs b/Essentials/PepperDashEssentials/Config/ConfigReader.cs index 5d5fac98..abf788f6 100644 --- a/Essentials/PepperDashEssentials/Config/ConfigReader.cs +++ b/Essentials/PepperDashEssentials/Config/ConfigReader.cs @@ -1,138 +1,150 @@ -using System; -using System.Linq; -using Crestron.SimplSharp; -using Crestron.SimplSharp.CrestronIO; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using PepperDash.Core; -using PepperDash.Essentials.Core.Config; - -namespace PepperDash.Essentials -{ - /// - /// Loads the ConfigObject from the file - /// - public class ConfigReader - { - public static EssentialsConfig ConfigObject { get; private set; } - - public static void LoadConfig2() - { - Debug.Console(0, "Using unmerged system/template configs."); - try - { - using (StreamReader fs = new StreamReader(string.Format(@"\NVRAM\program{0}\ConfigurationFile.json", InitialParametersClass.ApplicationNumber))) - { - var doubleObj = JObject.Parse(fs.ReadToEnd()); - ConfigObject = MergeConfigs(doubleObj).ToObject(); - } - } - catch (Exception e) - { - Debug.Console(0, "Config failed: \r{0}", e); - } - - } - - static JObject MergeConfigs(JObject doubleConfig) - { - var system = JObject.FromObject(doubleConfig["system"]); - var template = JObject.FromObject(doubleConfig["template"]); - var merged = new JObject(); - - // Put together top-level objects - if (system["info"] != null) - merged.Add("info", Merge(template["info"], system["info"])); - else - merged.Add("info", template["info"]); - - merged.Add("devices", MergeArraysOnTopLevelProperty(template["devices"] as JArray, system["devices"] as JArray, "uid")); - - if (system["rooms"] == null) - merged.Add("rooms", template["rooms"]); - else - merged.Add("rooms", MergeArraysOnTopLevelProperty(template["rooms"] as JArray, system["rooms"] as JArray, "key")); - - if (system["sourceLists"] == null) - merged.Add("sourceLists", template["sourceLists"]); - else - merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"])); - -#warning Make tie lines merge appropriately - if (template["tieLines"] != null) - merged.Add("tieLines", template["tieLines"]); - else if (system["tieLines"] != null) - merged.Add("tieLines", system["tieLines"]); - else - merged.Add("tieLines", new JArray()); - - Debug.Console(0, "MERGED RESULT: \x0d\x0a{0}", merged); - return merged; - } - - /// - /// Merges the contents of a base and a delta array, matching the entries on a top-level property - /// given by propertyName. Returns a merge of them. Items in the delta array that do not have - /// a matched item in base array will not be merged. - /// - static JArray MergeArraysOnTopLevelProperty(JArray a1, JArray a2, string propertyName) - { - var result = new JArray(); - if (a2 == null) - result = a1; - else if (a1 != null) - { - for (int i = 0; i < a1.Count(); i++) - { - var a1Dev = a1[i]; - // Try to get a system device and if found, merge it onto template - var a2Match = a2.FirstOrDefault(t => t[propertyName].Equals(a1Dev[propertyName]));// t.Value("uid") == tmplDev.Value("uid")); - if (a2Match != null) - { - var mergedItem = Merge(a1Dev, a2Match);// Merge(JObject.FromObject(a1Dev), JObject.FromObject(a2Match)); - result.Add(mergedItem); - } - else - result.Add(a1Dev); - } - } - return result; - } - - - /// - /// Helper for using with JTokens. Converts to JObject - /// - static JObject Merge(JToken t1, JToken t2) - { - return Merge(JObject.FromObject(t1), JObject.FromObject(t2)); - } - - /// - /// Merge b ONTO a - /// - /// - /// - static JObject Merge(JObject o1, JObject o2) - { - //Console.WriteLine("Merging {0}\ronto {1}", o2, o1); - foreach (var o2Prop in o2) - { - var o1Value = o1[o2Prop.Key]; - if (o1Value == null) - o1.Add(o2Prop.Key, o2Prop.Value); - else - { - JToken replacement = null; - if (o2Prop.Value.HasValues && o1Value.HasValues) // Drill down - replacement = Merge(JObject.FromObject(o1Value), JObject.FromObject(o2Prop.Value)); - else - replacement = o2Prop.Value; - o1[o2Prop.Key].Replace(replacement); - } - } - return o1; - } - - } +using System; +using System.Linq; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using PepperDash.Core; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials +{ + /// + /// Loads the ConfigObject from the file + /// + public class ConfigReader + { + public static EssentialsConfig ConfigObject { get; private set; } + + public static void LoadConfig2() + { + Debug.Console(0, "Using unmerged system/template configs."); + try + { + using (StreamReader fs = new StreamReader(string.Format(@"\NVRAM\program{0}\ConfigurationFile.json", InitialParametersClass.ApplicationNumber))) + { + var doubleObj = JObject.Parse(fs.ReadToEnd()); + ConfigObject = MergeConfigs(doubleObj).ToObject(); + + // Extract SystemUrl and TemplateUrl + + if (doubleObj["system_url"] != null) + { + ConfigObject.SystemUrl = doubleObj["system_url"].Value(); + } + + if (doubleObj["template_url"] != null) + { + ConfigObject.TemplateUrl= doubleObj["template_url"].Value(); + } + } + } + catch (Exception e) + { + Debug.Console(0, "Config failed: \r{0}", e); + } + + } + + static JObject MergeConfigs(JObject doubleConfig) + { + var system = JObject.FromObject(doubleConfig["system"]); + var template = JObject.FromObject(doubleConfig["template"]); + var merged = new JObject(); + + // Put together top-level objects + if (system["info"] != null) + merged.Add("info", Merge(template["info"], system["info"])); + else + merged.Add("info", template["info"]); + + merged.Add("devices", MergeArraysOnTopLevelProperty(template["devices"] as JArray, system["devices"] as JArray, "uid")); + + if (system["rooms"] == null) + merged.Add("rooms", template["rooms"]); + else + merged.Add("rooms", MergeArraysOnTopLevelProperty(template["rooms"] as JArray, system["rooms"] as JArray, "key")); + + if (system["sourceLists"] == null) + merged.Add("sourceLists", template["sourceLists"]); + else + merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"])); + +#warning Make tie lines merge appropriately + if (template["tieLines"] != null) + merged.Add("tieLines", template["tieLines"]); + else if (system["tieLines"] != null) + merged.Add("tieLines", system["tieLines"]); + else + merged.Add("tieLines", new JArray()); + + Debug.Console(0, "MERGED RESULT: \x0d\x0a{0}", merged); + return merged; + } + + /// + /// Merges the contents of a base and a delta array, matching the entries on a top-level property + /// given by propertyName. Returns a merge of them. Items in the delta array that do not have + /// a matched item in base array will not be merged. + /// + static JArray MergeArraysOnTopLevelProperty(JArray a1, JArray a2, string propertyName) + { + var result = new JArray(); + if (a2 == null) + result = a1; + else if (a1 != null) + { + for (int i = 0; i < a1.Count(); i++) + { + var a1Dev = a1[i]; + // Try to get a system device and if found, merge it onto template + var a2Match = a2.FirstOrDefault(t => t[propertyName].Equals(a1Dev[propertyName]));// t.Value("uid") == tmplDev.Value("uid")); + if (a2Match != null) + { + var mergedItem = Merge(a1Dev, a2Match);// Merge(JObject.FromObject(a1Dev), JObject.FromObject(a2Match)); + result.Add(mergedItem); + } + else + result.Add(a1Dev); + } + } + return result; + } + + + /// + /// Helper for using with JTokens. Converts to JObject + /// + static JObject Merge(JToken t1, JToken t2) + { + return Merge(JObject.FromObject(t1), JObject.FromObject(t2)); + } + + /// + /// Merge b ONTO a + /// + /// + /// + static JObject Merge(JObject o1, JObject o2) + { + //Console.WriteLine("Merging {0}\ronto {1}", o2, o1); + foreach (var o2Prop in o2) + { + var o1Value = o1[o2Prop.Key]; + if (o1Value == null) + o1.Add(o2Prop.Key, o2Prop.Value); + else + { + JToken replacement = null; + if (o2Prop.Value.HasValues && o1Value.HasValues) // Drill down + replacement = Merge(JObject.FromObject(o1Value), JObject.FromObject(o2Prop.Value)); + else + replacement = o2Prop.Value; + o1[o2Prop.Key].Replace(replacement); + } + } + return o1; + } + + } } \ No newline at end of file diff --git a/Essentials/PepperDashEssentials/Config/EssentialsConfig.cs b/Essentials/PepperDashEssentials/Config/EssentialsConfig.cs index de83739c..e158c810 100644 --- a/Essentials/PepperDashEssentials/Config/EssentialsConfig.cs +++ b/Essentials/PepperDashEssentials/Config/EssentialsConfig.cs @@ -1,29 +1,57 @@ -using System; -using System.Collections.Generic; -using Crestron.SimplSharp.CrestronIO; - -using Newtonsoft.Json; -using PepperDash.Core; -using PepperDash.Essentials.Core.Config; - -namespace PepperDash.Essentials -{ - /// - /// Loads the ConfigObject from the file - /// - public class EssentialsConfig : BasicConfig - { - [JsonProperty("rooms")] - public List Rooms { get; private set; } - } - - /// - /// - /// - public class SystemTemplateConfigs - { - public EssentialsConfig System { get; set; } - - public EssentialsConfig Template { get; set; } - } +using System; +using System.Collections.Generic; +using Crestron.SimplSharp.CrestronIO; + +using Newtonsoft.Json; +using PepperDash.Core; +using PepperDash.Essentials.Core.Config; +using System.Text.RegularExpressions; + +namespace PepperDash.Essentials +{ + /// + /// Loads the ConfigObject from the file + /// + public class EssentialsConfig : BasicConfig + { + public string SystemUrl { get; set; } + public string TemplateUrl { get; set; } + + public string SystemUuid + { + get + { + var result = Regex.Match(SystemUrl, @"https?:\/\/.*\/templates\/(.*)#.*"); + + string uuid = result.Groups[1].Value; + + return uuid; + } + } + + public string TemplateUuid + { + get + { + var result = Regex.Match(TemplateUrl, @"https?:\/\/.*\/templates\/(.*)#.*"); + + string uuid = result.Groups[1].Value; + + return uuid; + } + } + + [JsonProperty("rooms")] + public List Rooms { get; private set; } + } + + /// + /// + /// + public class SystemTemplateConfigs + { + public EssentialsConfig System { get; set; } + + public EssentialsConfig Template { get; set; } + } } \ No newline at end of file diff --git a/Essentials/PepperDashEssentials/Fusion/FusionSystemController.cs b/Essentials/PepperDashEssentials/Fusion/FusionSystemController.cs index 3deeccb9..03f41cb3 100644 --- a/Essentials/PepperDashEssentials/Fusion/FusionSystemController.cs +++ b/Essentials/PepperDashEssentials/Fusion/FusionSystemController.cs @@ -321,7 +321,7 @@ namespace PepperDash.Essentials.Fusion "\n" + "\n"; - Debug.Console(1, this, "Sending Fusion ActionRequest: \n{0}", actionRequest); + Debug.Console(2, this, "Sending Fusion ActionRequest: \n{0}", actionRequest); FusionRoom.ExtenderFusionRoomDataReservedSigs.ActionQuery.StringValue = actionRequest; } @@ -336,21 +336,12 @@ namespace PepperDash.Essentials.Fusion { DateTime now = DateTime.Today; - //string currentTime = string.Format("Current time: {0:D4}-{1:D2}-{2:D2}T{3:D2}:{4:D2}:{5:D2}", now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); - string currentTime = now.ToString("s"); - Debug.Console(1, this, "Current time: {0}", currentTime); - - //Debug.Console(1, this, "Current time: {0}", now.ToString("d")); - - //string requestTest = - // string.Format("{0}{1}2017-05-02T00:00:0024", requestID, GUID); - string requestTest = string.Format("FullSchedleRequest{0}{1}24", RoomGuid, currentTime); - Debug.Console(1, this, "Sending Fusion ScheduleQuery: \n{0}", requestTest); + Debug.Console(2, this, "Sending Fusion ScheduleQuery: \n{0}", requestTest); FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.ScheduleQuery.StringValue = requestTest; @@ -465,7 +456,7 @@ namespace PepperDash.Essentials.Fusion "" + ""; - Debug.Console(1, this, "Sending CreateMeeting Request: \n{0}", createMeetingRequest); + Debug.Console(2, this, "Sending CreateMeeting Request: \n{0}", createMeetingRequest); FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.CreateMeeting.StringValue = createMeetingRequest; @@ -482,7 +473,7 @@ namespace PepperDash.Essentials.Fusion /// void ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args) { - Debug.Console(1, this, "Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); + Debug.Console(2, this, "Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); if (args.Sig == FusionRoom.ExtenderFusionRoomDataReservedSigs.ActionQueryResponse) @@ -578,7 +569,7 @@ namespace PepperDash.Essentials.Fusion /// void FusionRoomSchedule_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args) { - Debug.Console(1, this, "Scehdule Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); + Debug.Console(2, this, "Scehdule Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); if (args.Sig == FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.ScheduleResponse) @@ -674,7 +665,7 @@ namespace PepperDash.Essentials.Fusion } else if (args.Sig == FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.CreateResponse) { - Debug.Console(1, this, "Create Meeting Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); + Debug.Console(2, this, "Create Meeting Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); } } diff --git a/Essentials/PepperDashEssentials/PepperDashEssentials.projectinfo b/Essentials/PepperDashEssentials/PepperDashEssentials.projectinfo index 8f657ecbac8d91a5d0cc2fe58f0bed1a35e4e5f8..e2cb3d80008506d9f6e89b712ccdfe50f7c62ae0 100644 GIT binary patch delta 1752 zcmV;}1}FK(4#^IXg@5wVqqbhtFH`#JWxiVF_0z1GpEgatYzt~bt!Kku<@6Q(IF}z6 z^kZ*l_rdngr`tORZ+7<|?caN}_vv`=-u}JagMIq=(asLFn^U`!N5Ajy``xO3TP!cq zr$wDl+o~?|=J)-5T~EL7@B8}4f8XCXxBdOTzpv}tZ|8qHDSwvnug25W52)+Hj{Id^ z{WSG@wmh$%6=lB67WvN}T2YKvf3B9P+M-%!CB`nFom7hz5n=Y_@|II*UijH3-Ayxkx|rm%*VVe7=EwDP zUR>sOichN5^?#e{Syj&Ry7}mlk$}CAe#z*gFN$TcSTCLx_2Me4^Pi*^L=(uzcxUG! z{eSNv0snH{uGa0#to>PIS?c7AY+0P=P3thcN1tw(dL8)}S+P8(4;Pd2+P%9^-*~eU zeScP#)G8P={kOOOU>#52w>lXMgAW_xAQ5PVY|+cBXp|CJ*mV zKAjyL9Gp{2nU&3hP}**2@w}R5<5Fh? zCbRSV+4MXkrk>uLOb#BL@9oa=$-%?j-Mxd!?(8-*V?YMeaSOm-cREae|L>cF2e+Do z({`TM%e*DqvRE&RX$C80L{Q0h@6-I#Pw(wNe1EX}@c!=pPM&{yzB}2^C)4})&hO{h zgImnY#%_YSxHg%? z>BCR&W#@ad^V?{+0BkTnw*dY%=O^g%|9$iE@K*EjdDiAv*>y*P9_;P!<$Jq(S$6M$ zOn>*@L3V%kaF+=A>A~K^^MmXbGtvPZ%*idlf6Y1R^!oq4S=rsW)wI0I7gd{gW`!8` z(|l*LcW-BZ?_vJw!@cS3-u<0?`suyt!<`3{{1&qk!VM`=Z#5@h zorTk}bMWvU@$k-cvNPGgfA7K0gS{Cket(LB@&~*5&TXc{f(&Nj7J$FzOxXVZUpNVS z;UqXvsrZmh3Paen9iKj!?4DC(F+I3{zW-plvzOE2}b{-+1K z6j)Esr{@RL2Rl3apT-IA0}AMU3vjomx8KYE3(4FG%RRgu)Ck4z?UR+9-J9+1KFA;J zkqh(i;e*NSUcNt_?d|XH+#jHL9DimQN8AkgJ%}Ig@c)JL(22a`L+AzGpMLuA;r?uz zXE`~H(}zT**<^Nb?>zf-=i&V@z`Frr7%?9EOwndetH=yqaI1 zE!(_4&!!!5n9cSdJlxF=KAnAf{^^6+YQwodyiMSo$V1GVt0sf}> zxLvRRFPxT6IPHyN-L%!>xNYlVvL?5BU}}g^ll|HL^#1O{$*1@4XXg)hc6L9_XVYwN z_UWgShXYe{1Mtv3-`vG}OwSEH|G#jGIuW)T%eV8Azz z4|WbF`GZgQ_wUc9fya6i$bT?^yBYB9rz76q|NACkuMAg?0=>+54nFS_%1GJ7L+z9jbr0;e0|3a#FBIYp4%-`jX+~?w_9 zgsbI%e&O&apG_v&!TxkQd$4=|{^a4qgZ=!|2m1#HlOUVg1sek!Ou#LG-+lsyhw}fz z3F$<}ZWOP7;`v5>f4(!lzjJ>!%crx0?7_jk+5Y6ged5{sJG;}#9Uon~i5#>t=&=#^lr8>Hfj=AlsYL7|GGU|A2Bk#Lo8~ uJec~kF+{VQsoEi01fgH@{a^A+cy+xv*OeU_*}80Hp#KkfS2Tx+BLDzIWA=&w delta 1749 zcmV;`1}gc<4#p0Ug@0myo6>hL^VKS^pJvVcv}y8XThLe3d^Y@5PG8ZFbNO*WKlXNZ zA8ha3-`>0bW_S0|-tMFOd*i*md!HU0>~HTpc(k)a?dH_(1hgKA$m0(a1287vJL;bba7QffmO`9)X2wDT=r!idA+2U;WCcC(? z)grHDnvQ3)qAjXrR$}n-*-5on5fx@%E^j%9=7pbq+TApzr;ABGdtI&TX?|Q!=f!1i zX?RktuHRJ8s(*5p*Ud+dj1263^h-t`eNiln#d`6qs25jRo&O}YAeulz#ydL?>Hm8V z3HX=mcC~I_X6?@!&r&B}WXs|_Z(4`pJ^FOR)a%H<$cp7LeYlvE*Y4eY`o^1;==-y> zq*lS0>A&5BPw(UH4r#hH`8L7AXZfeoorkmOg9m%F$$#$N!|B1j>8I1lbTZq|_NKcJ zsHM!x=0PZJH?(+OO|$Z6a|$-`m{96zzRH)gd^x4QK6>;$L+bk>sZVN}#JXCJUl)s2 z`Fft!E0VqO)BLiS=C9YQRaLhNP-!^LvV4ECzjyy(mYsjP`*7#}!}Faizqh~t;NIkX zw&&CEJ%6CfJGbxShB)mgo#*v3 zZ^^bS*2`j=!AcnsRPx>XH2?I|d;1R`>^{7|yMMov=bxVMPWJQ3^!~l``*{{}$@|MjZa%H-87Wn!jgjn3Hh6_NMvd)BXF|?0%N*JUlpma4_AUd^&yj>AmcH zZ+3ng4Htk7=I0i`zvlb|eg401J|5m`K0eRd{3^TdNYI15{k?o|cQ4EC9qixR+dIha z&wn275+Of5*n4<>klkWNI)H;Yxdr&IIVYW7|KB$&yF0gbZhyXWo9VD1gPFJm;IBCow!i-uPQqR|2@X^$ zK4g=^5O!_H{zKB~(+8iPXM596>3@^y?BPLnFgw4ud;k2wB=Es*0vSxgEdbv%2{-lk z|H4VQ7fyl$dQ#Q-OLF0}^7Zv{8qUGN?*07JorCFw=yR}hFv}*ppFTLa_h5Q{@PBZ! zdq1!iH$V)g;1+Oint~g;`+wmK><`Vr?~f65G|XtT)DWR2`?LM&{oRL?Pw(H)&L8gV?0%ZhrrF-?(@!T4 z2d3r*;KB6VqKo&Ko*R1pf8i8$B5XI7Z|5a}ADEadpFP;iC!}H?-lu#kWr;q0uyZiU zAAGvMe}6U&Jl2~)hT7|9z<;-&j(C6n@0*0ZPCV^K@FKrzDPLBdck<~EX+>gse|B$Y zMg*J9$d|l7z4vK0onV|hp$Xprts@CH!n{4{dtLp%km{X?IgB#%cex|?`T3^@IR&i` zKc(n(cCfcYnVyf!&_Yu8;p061Wo$JAbTS<>w_D9&Uzx`{@|$ z^8Yon(fPp6O($k{Lr!{{wb^)@XG}ibo$en@53;=}jgd0W_aEdrxiQmw4<1bY r*%+eP%~b6WErQT5`Tj5YCA_*`oa@RCjci@EGSL4AO;|MAiX#932J`G^ diff --git a/Essentials/PepperDashEssentials/UI/CotijaInterfaceController.cs b/Essentials/PepperDashEssentials/UI/CotijaInterfaceController.cs index 7aa3752b..8f8bfc9c 100644 --- a/Essentials/PepperDashEssentials/UI/CotijaInterfaceController.cs +++ b/Essentials/PepperDashEssentials/UI/CotijaInterfaceController.cs @@ -14,77 +14,134 @@ namespace PepperDash.Essentials { public class CotijaInterfaceController : Device { - StreamReader Reader; + GenericHttpSseClient SseClient; - Crestron.SimplSharp.Net.Connection Connection; + CCriticalSection FileLock; + + string ServerUrl; public CotijaInterfaceController(string key) : base(key) { - CrestronConsole.AddNewConsoleCommand(InitializeClientAndEventStream, "InitializeHttpClient", "Initializes a new HTTP client connection to a specified URL", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(RegisterRoomToServer, "InitializeHttpClient", "Initializes a new HTTP client connection to a specified URL", ConsoleAccessLevelEnum.AccessOperator); } - public void InitializeClientAndEventStream(string url) + /// + /// Registers the room with the server + /// + /// URL of the server, including the port number, if not 80. Format: "serverUrlOrIp:port" + void RegisterRoomToServer(string url) { try { - HttpClient webClient = new HttpClient(); - webClient.Verbose = true; - HttpClientRequest request = new HttpClientRequest(); - request.Url = new UrlParser(url); - request.Header.AddHeader(new HttpHeader("Accept", "text/event-stream")); - request.KeepAlive = true; + ServerUrl = url; - /// Experimenting with grabbing connection before the request - Connection = webClient.ConnectNew("192.168.1.120", 3000); - Debug.Console(1, this, "Connection Port: {0}", Connection.LocalEndPointPort); - Reader = new StreamReader(Connection); - Connection.OnBytesReceived += new EventHandler(DataConnection_OnBytesReceived); + string filePath = string.Format(@"\NVRAM\Program{0}\configurationFile.json", Global.ControlSystem.ProgramNumber); + string postBody = null; - /// Not sure if this is starting a new connection - webClient.DispatchAsync(request, StreamConnectionCallback); + if (string.IsNullOrEmpty(filePath)) + { + Debug.Console(0, this, "Error reading file. No path specified."); + return; + } + + FileLock = new CCriticalSection(); + + if (FileLock.TryEnter()) + { + Debug.Console(1, this, "Reading Configuration File"); + + postBody = File.ReadToEnd(filePath, Encoding.ASCII); + + Debug.Console(2, this, "{0}", postBody); + + FileLock.Leave(); + } + + if (string.IsNullOrEmpty(postBody)) + { + Debug.Console(1, "Post Body is null or empty"); + } + else + { + HttpClient Client = new HttpClient(); + + HttpClientRequest Request = new HttpClientRequest(); + + Client.Verbose = true; + Client.KeepAlive = true; + + string uuid = Essentials.ConfigReader.ConfigObject.SystemUuid; + + url = string.Format("http://{0}/api/system/join/{1}", ServerUrl, uuid); + + Request.Url.Parse(url); + Request.RequestType = RequestType.Post; + Request.Header.SetHeaderValue("Content-Type", "application/json"); + Request.ContentString = postBody; + + Client.DispatchAsync(Request, PostConnectionCallback); + } } catch (Exception e) { - Debug.Console(1, this, "Error Initializing Cotija client:\n{0}", e); + Debug.Console(0, this, "Error Initilizing Room: {0}", e); + } + + } + + /// + /// The callback that fires when we get a response from our registration attempt + /// + /// + /// + void PostConnectionCallback(HttpClientResponse resp, HTTP_CALLBACK_ERROR err) + { + try + { + if (resp.Code == 200) + { + Debug.Console(0, this, "Initializing SSE Client."); + + if (SseClient == null) + { + SseClient = new GenericHttpSseClient(string.Format("{0}-SseClient", Key), Name); + } + else + { + if (SseClient.IsConnected) + { + SseClient.Disconnect(); + } + + string uuid = Essentials.ConfigReader.ConfigObject.SystemUuid; + + SseClient.Url = string.Format("http://{0}/api/system/stream/{1}", ServerUrl, uuid); + + SseClient.Connect(); + } + + CommunicationGather LineGathered = new CommunicationGather(SseClient, "\x0d\x0a"); + + LineGathered.LineReceived += new EventHandler(LineGathered_LineReceived); + + + } + else + { + Debug.Console(0, this, "Unable to initialize SSE Client"); + } + } + catch (Exception e) + { + Debug.Console(1, this, "Error Initializeing SSE Client: {0}", e); } } - // This callback happens but none of the events would fire (when not commented out) - void StreamConnectionCallback(HttpClientResponse resp, HTTP_CALLBACK_ERROR err) + void LineGathered_LineReceived(object sender, GenericCommMethodReceiveTextArgs e) { - Debug.Console(1, this, "Connection Port: {0}", resp.DataConnection.LocalEndPointPort); - Debug.Console(1, this, "Connections are equal {0}", resp.DataConnection == Connection); - Debug.Console(1, this, "Callback Fired"); - //resp.DataConnection.OnBytesReceived += new EventHandler(DataConnection_OnBytesReceived); - //Debug.Console(1, this, "Received: '{0}'", resp.ContentString); - //resp.OnTransferEnd += new Crestron.SimplSharp.Net.TransferEndEventHandler(resp_OnTransferEnd); - //resp.OnTransferProgress += new Crestron.SimplSharp.Net.TransferProgressEventHandler(resp_OnTransferProgress); - //resp.OnTransferStart += new Crestron.SimplSharp.Net.TransferStartEventHandler(resp_OnTransferStart); + Debug.Console(1, this, "Received from Node Server: '{0}'", e.Text); } - // We could never get this event handler to fire - void DataConnection_OnBytesReceived(object sender, EventArgs e) - { - Debug.Console(1, this, "OnBytesReceived Event Fired."); - Debug.Console(1, this, "Event: Received: '{0}'", Reader.ReadToEnd()); - } - - //void resp_OnTransferStart(object sender, Crestron.SimplSharp.Net.TransferStartEventArgs e) - //{ - // Debug.Console(1, this, "OnTransferStart"); - //} - - //void resp_OnTransferProgress(object sender, Crestron.SimplSharp.Net.TransferProgressEventArgs e) - //{ - // Debug.Console(1, this, "OnTransferProgress"); - //} - - - - //void resp_OnTransferEnd(object sender, Crestron.SimplSharp.Net.TransferEndEventArgs e) - //{ - // Debug.Console(1, this, "OnTransferEnd"); - //} } } \ No newline at end of file