diff --git a/PepperDashEssentials/Room/Cotija/CotijaConfig.cs b/PepperDashEssentials/AppServer/CotijaConfig.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/CotijaConfig.cs
rename to PepperDashEssentials/AppServer/CotijaConfig.cs
diff --git a/PepperDashEssentials/Room/Cotija/CotijaDdvc01DeviceBridge.cs b/PepperDashEssentials/AppServer/CotijaDdvc01DeviceBridge.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/CotijaDdvc01DeviceBridge.cs
rename to PepperDashEssentials/AppServer/CotijaDdvc01DeviceBridge.cs
diff --git a/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs b/PepperDashEssentials/AppServer/CotijaSystemController.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/CotijaSystemController.cs
rename to PepperDashEssentials/AppServer/CotijaSystemController.cs
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IChannelExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IChannelExtensions.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IChannelExtensions.cs
rename to PepperDashEssentials/AppServer/DeviceTypeInterfaces/IChannelExtensions.cs
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IColorExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IColorExtensions.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IColorExtensions.cs
rename to PepperDashEssentials/AppServer/DeviceTypeInterfaces/IColorExtensions.cs
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IDPadExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDPadExtensions.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IDPadExtensions.cs
rename to PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDPadExtensions.cs
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IDvrExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDvrExtensions.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IDvrExtensions.cs
rename to PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDvrExtensions.cs
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/INumericExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/INumericExtensions.cs
similarity index 99%
rename from PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/INumericExtensions.cs
rename to PepperDashEssentials/AppServer/DeviceTypeInterfaces/INumericExtensions.cs
index 4f35e238..376ed57b 100644
--- a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/INumericExtensions.cs
+++ b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/INumericExtensions.cs
@@ -42,8 +42,8 @@ namespace PepperDash.Essentials.Room.Cotija
controller.RemoveAction(prefix + "num6");
controller.RemoveAction(prefix + "num7");
controller.RemoveAction(prefix + "num8");
- controller.RemoveAction(prefix + "num9");
- controller.RemoveAction(prefix + "numDash");
+ controller.RemoveAction(prefix + "num9");
+ controller.RemoveAction(prefix + "numDash");
controller.RemoveAction(prefix + "numEnter");
}
}
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IPowerExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IPowerExtensions.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IPowerExtensions.cs
rename to PepperDashEssentials/AppServer/DeviceTypeInterfaces/IPowerExtensions.cs
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs
rename to PepperDashEssentials/AppServer/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ITransportExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/ITransportExtensions.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ITransportExtensions.cs
rename to PepperDashEssentials/AppServer/DeviceTypeInterfaces/ITransportExtensions.cs
diff --git a/PepperDashEssentials/Room/Cotija/Interfaces.cs b/PepperDashEssentials/AppServer/Interfaces.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/Interfaces.cs
rename to PepperDashEssentials/AppServer/Interfaces.cs
diff --git a/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs b/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs
new file mode 100644
index 00000000..e35e4839
--- /dev/null
+++ b/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs
@@ -0,0 +1,151 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+using PepperDash.Essentials.Devices.Common.Codec;
+using PepperDash.Essentials.Devices.Common.VideoCodec;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for a VideoCodecBase
+ ///
+ public class VideoCodecBaseMessenger
+ {
+ ///
+ ///
+ ///
+ public VideoCodecBase Codec { get; private set; }
+
+ public CotijaSystemController AppServerController { get; private set; }
+
+ public string MessagePath { get; private set; }
+
+ ///
+ ///
+ ///
+ ///
+ public VideoCodecBaseMessenger(VideoCodecBase codec, string messagePath)
+ {
+ if (codec == null)
+ throw new ArgumentNullException("codec");
+ if (string.IsNullOrEmpty(messagePath))
+ throw new ArgumentException("messagePath must not be empty or null");
+
+ MessagePath = messagePath;
+ Codec = codec;
+ codec.CallStatusChange += new EventHandler(codec_CallStatusChange);
+ }
+
+ ///
+ /// Registers this codec's messaging with an app server controller
+ ///
+ ///
+ public void RegisterWithAppServer(CotijaSystemController appServerController)
+ {
+ if (appServerController == null)
+ throw new ArgumentNullException("appServerController");
+
+ AppServerController = appServerController;
+
+ appServerController.AddAction("/device/videoCodec/dial", new Action(s => Codec.Dial(s)));
+ appServerController.AddAction("/device/videoCodec/endCallById", new Action(s =>
+ {
+ var call = GetCallWithId(s);
+ if (call != null)
+ Codec.EndCall(call);
+ }));
+ appServerController.AddAction(MessagePath + "/endAllCalls", new Action(() => Codec.EndAllCalls()));
+ appServerController.AddAction(MessagePath + "/dtmf", new Action(s => Codec.SendDtmf(s)));
+ appServerController.AddAction(MessagePath + "/rejectById", new Action(s =>
+ {
+ var call = GetCallWithId(s);
+ if (call != null)
+ Codec.RejectCall(call);
+ }));
+ appServerController.AddAction(MessagePath + "/acceptById", new Action(s =>
+ {
+ var call = GetCallWithId(s);
+ if (call != null)
+ Codec.AcceptCall(call);
+ }));
+ appServerController.AddAction(MessagePath + "/privacyModeOn", new Action(() => Codec.PrivacyModeOn()));
+ appServerController.AddAction(MessagePath + "/privacyModeOff", new Action(() => Codec.PrivacyModeOff()));
+ appServerController.AddAction(MessagePath + "/privacyModeToggle", new Action(() => Codec.PrivacyModeToggle()));
+ appServerController.AddAction(MessagePath + "/sharingStart", new Action(() => Codec.StartSharing()));
+ appServerController.AddAction(MessagePath + "/sharingStop", new Action(() => Codec.StopSharing()));
+ appServerController.AddAction(MessagePath + "/standbyOn", new Action(() => Codec.StandbyActivate()));
+ appServerController.AddAction(MessagePath + "/standbyOff", new Action(() => Codec.StandbyDeactivate()));
+ }
+
+ ///
+ /// Helper to grab a call with string ID
+ ///
+ ///
+ ///
+ CodecActiveCallItem GetCallWithId(string id)
+ {
+ return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
+ }
+
+ ///
+ /// Handler for codec changes
+ ///
+ void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
+ {
+ PostStatusMessage(new
+ {
+ vtc = GetVtcCallsMessageObject()
+ });
+
+ }
+
+ ///
+ /// Helper method to build call status for vtc
+ ///
+ ///
+ object GetVtcCallsMessageObject()
+ {
+ var info = Codec.CodecInfo;
+ return new
+ {
+ isInCall = Codec.IsInCall,
+ isReady = Codec.IsReady,
+ privacyModeIsOn = Codec.PrivacyModeIsOnFeedback.BoolValue,
+ sharingContentIsOn = Codec.SharingContentIsOnFeedback.BoolValue,
+ sharingSource = Codec.SharingSourceFeedback.StringValue,
+ standbyIsOn = Codec.StandbyIsOnFeedback.StringValue,
+ calls = Codec.ActiveCalls,
+ info = new
+ {
+ autoAnswerEnabled = info.AutoAnswerEnabled,
+ e164Alias = info.E164Alias,
+ h323Id = info.H323Id,
+ ipAddress = info.IpAddress,
+ multiSiteEnabled = info.MultiSiteOptionIsEnabled,
+ sipPhoneNumber = info.SipPhoneNumber,
+ sipURI = info.SipUri
+ },
+ showSelfViewByDefault = Codec.ShowSelfViewByDefault
+ };
+ }
+
+ ///
+ /// Helper for posting status message
+ ///
+ /// The contents of the content object
+ void PostStatusMessage(object contentObject)
+ {
+ AppServerController.SendMessageToServer(JObject.FromObject(new
+ {
+ type = MessagePath,
+ content = contentObject
+ }));
+ }
+ }
+}
\ No newline at end of file
diff --git a/PepperDashEssentials/Room/Cotija/RoomBridges/CotijaBridgeBase.cs b/PepperDashEssentials/AppServer/RoomBridges/CotijaBridgeBase.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/RoomBridges/CotijaBridgeBase.cs
rename to PepperDashEssentials/AppServer/RoomBridges/CotijaBridgeBase.cs
diff --git a/PepperDashEssentials/Room/Cotija/RoomBridges/CotijaDdvc01RoomBridge.cs b/PepperDashEssentials/AppServer/RoomBridges/CotijaDdvc01RoomBridge.cs
similarity index 96%
rename from PepperDashEssentials/Room/Cotija/RoomBridges/CotijaDdvc01RoomBridge.cs
rename to PepperDashEssentials/AppServer/RoomBridges/CotijaDdvc01RoomBridge.cs
index 930a94b7..c47d11b3 100644
--- a/PepperDashEssentials/Room/Cotija/RoomBridges/CotijaDdvc01RoomBridge.cs
+++ b/PepperDashEssentials/AppServer/RoomBridges/CotijaDdvc01RoomBridge.cs
@@ -1,670 +1,670 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-using Crestron.SimplSharp.Reflection;
-using Crestron.SimplSharpPro.EthernetCommunication;
-
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Config;
-using PepperDash.Essentials.Room.Config;
-
-
-namespace PepperDash.Essentials.Room.Cotija
-{
- public class CotijaDdvc01RoomBridge : CotijaBridgeBase, IDelayedConfiguration
- {
- public class BoolJoin
- {
- ///
- /// 301
- ///
- public const uint RoomIsOn = 301;
-
- ///
- /// 51
- ///
- public const uint ActivitySharePress = 51;
- ///
- /// 52
- ///
- public const uint ActivityPhoneCallPress = 52;
- ///
- /// 53
- ///
- public const uint ActivityVideoCallPress = 53;
-
- ///
- /// 1
- ///
- public const uint MasterVolumeIsMuted = 1;
- ///
- /// 1
- ///
- public const uint MasterVolumeMuteToggle = 1;
-
- ///
- /// 61
- ///
- public const uint ShutdownCancel = 61;
- ///
- /// 62
- ///
- public const uint ShutdownEnd = 62;
- ///
- /// 63
- ///
- public const uint ShutdownStart = 63;
-
-
-
- ///
- /// 72
- ///
- public const uint SourceHasChanged = 72;
- ///
- /// 501
- ///
- public const uint ConfigIsReady = 501;
- }
-
- public class UshortJoin
- {
- ///
- /// 1
- ///
- public const uint MasterVolumeLevel = 1;
-
- ///
- /// 61
- ///
- public const uint ShutdownPromptDuration = 61;
- }
-
- public class StringJoin
- {
- ///
- /// 71
- ///
- public const uint SelectedSourceKey = 71;
-
- ///
- /// 501
- ///
- public const uint ConfigRoomName = 501;
- ///
- /// 502
- ///
- public const uint ConfigHelpMessage = 502;
- ///
- /// 503
- ///
- public const uint ConfigHelpNumber = 503;
- ///
- /// 504
- ///
- public const uint ConfigRoomPhoneNumber = 504;
- ///
- /// 505
- ///
- public const uint ConfigRoomURI = 505;
- ///
- /// 401
- ///
- public const uint UserCodeToSystem = 401;
- ///
- /// 402
- ///
- public const uint ServerUrl = 402;
- }
-
- ///
- /// Fires when config is ready to go
- ///
- public event EventHandler ConfigurationIsReady;
-
- public ThreeSeriesTcpIpEthernetIntersystemCommunications EISC { get; private set; }
-
- ///
- ///
- ///
- public bool ConfigIsLoaded { get; private set; }
-
- public override string RoomName
- {
- get {
- var name = EISC.StringOutput[StringJoin.ConfigRoomName].StringValue;
- return string.IsNullOrEmpty(name) ? "Not Loaded" : name;
- }
- }
-
- CotijaDdvc01DeviceBridge SourceBridge;
-
-
- ///
- ///
- ///
- ///
- ///
- ///
- public CotijaDdvc01RoomBridge(string key, string name, uint ipId)
- : base(key, name)
- {
- try
- {
- EISC = new ThreeSeriesTcpIpEthernetIntersystemCommunications(ipId, "127.0.0.2", Global.ControlSystem);
- var reg = EISC.Register();
- if (reg != Crestron.SimplSharpPro.eDeviceRegistrationUnRegistrationResponse.Success)
- Debug.Console(0, this, "Cannot connect EISC at IPID {0}: \r{1}", ipId, reg);
-
- SourceBridge = new CotijaDdvc01DeviceBridge(key + "-sourceBridge", "DDVC01 source bridge", EISC);
- DeviceManager.AddDevice(SourceBridge);
- }
- catch (Exception)
- {
- throw;
- }
- }
-
- ///
- /// Finish wiring up everything after all devices are created. The base class will hunt down the related
- /// parent controller and link them up.
- ///
- ///
- public override bool CustomActivate()
- {
- Debug.Console(0, this, "Final activation. Setting up actions and feedbacks");
- SetupFunctions();
- SetupFeedbacks();
-
- EISC.SigChange += EISC_SigChange;
- EISC.OnlineStatusChange += (o, a) =>
- {
- Debug.Console(1, this, "DDVC EISC online={0}. Config is ready={1}", a.DeviceOnLine, EISC.BooleanOutput[BoolJoin.ConfigIsReady].BoolValue);
- if (a.DeviceOnLine && EISC.BooleanOutput[BoolJoin.ConfigIsReady].BoolValue)
- LoadConfigValues();
- };
- // load config if it's already there
- if (EISC.IsOnline && EISC.BooleanOutput[BoolJoin.ConfigIsReady].BoolValue) // || EISC.BooleanInput[BoolJoin.ConfigIsReady].BoolValue)
- LoadConfigValues();
-
-
- CrestronConsole.AddNewConsoleCommand(s =>
- {
- for (uint i = 1; i < 1000; i++)
- {
- if (s.ToLower().Equals("b"))
- {
- CrestronConsole.ConsoleCommandResponse("D{0,6} {1} - ", i, EISC.BooleanOutput[i].BoolValue);
- }
- else if (s.ToLower().Equals("u"))
- {
- CrestronConsole.ConsoleCommandResponse("U{0,6} {1,8} - ", i, EISC.UShortOutput[i].UShortValue);
- }
- else if (s.ToLower().Equals("s"))
- {
- var val = EISC.StringOutput[i].StringValue;
- if(!string.IsNullOrEmpty(val))
- CrestronConsole.ConsoleCommandResponse("S{0,6} {1}\r", i, EISC.StringOutput[i].StringValue);
- }
-
- }
- }, "mobilebridgedump", "Dumps DDVC01 bridge EISC data b,u,s", ConsoleAccessLevelEnum.AccessOperator);
-
- CrestronConsole.AddNewConsoleCommand(s => LoadConfigValues(), "loadddvc", "", ConsoleAccessLevelEnum.AccessOperator);
-
- return base.CustomActivate();
- }
-
-
- ///
- /// Setup the actions to take place on various incoming API calls
- ///
- void SetupFunctions()
- {
-
- Parent.AddAction(@"/room/room1/status", new Action(SendFullStatus));
-
- Parent.AddAction(@"/room/room1/source", new Action(c =>
- {
- EISC.SetString(StringJoin.SelectedSourceKey, c.SourceListItem);
- EISC.PulseBool(BoolJoin.SourceHasChanged);
- }));
-
- Parent.AddAction(@"/room/room1/defaultsource", new Action(() =>
- EISC.PulseBool(BoolJoin.ActivitySharePress)));
-
- Parent.AddAction(@"/room/room1/volumes/master/level", new Action(u =>
- EISC.SetUshort(UshortJoin.MasterVolumeLevel, u)));
- Parent.AddAction(@"/room/room1/volumes/master/muteToggle", new Action(() =>
- EISC.PulseBool(BoolJoin.MasterVolumeIsMuted)));
-
- Parent.AddAction(@"/room/room1/shutdownStart", new Action(() =>
- EISC.PulseBool(BoolJoin.ShutdownStart)));
- Parent.AddAction(@"/room/room1/shutdownEnd", new Action(() =>
- EISC.PulseBool(BoolJoin.ShutdownEnd)));
- Parent.AddAction(@"/room/room1/shutdownCancel", new Action(() =>
- EISC.PulseBool(BoolJoin.ShutdownCancel)));
-
-
- // Source Device (Current Source)'
-
- SourceDeviceMapDictionary sourceJoinMap = new SourceDeviceMapDictionary();
-
- var prefix = @"/device/currentSource/";
-
- foreach (var item in sourceJoinMap)
- {
- Parent.AddAction(string.Format("{0}{1}", prefix, item.Key), new PressAndHoldAction(b => EISC.SetBool(item.Value, b)));
- }
- }
-
- ///
- /// Links feedbacks to whatever is gonna happen!
- ///
- void SetupFeedbacks()
- {
- // Power
- EISC.SetBoolSigAction(BoolJoin.RoomIsOn, b =>
- PostStatusMessage(new
- {
- isOn = b
- }));
-
- // Source change things
- EISC.SetSigTrueAction(BoolJoin.SourceHasChanged, () =>
- PostStatusMessage(new
- {
- selectedSourceKey = EISC.StringOutput[StringJoin.SelectedSourceKey].StringValue
- }));
-
- // Volume things
- EISC.SetUShortSigAction(UshortJoin.MasterVolumeLevel, u =>
- PostStatusMessage(new
- {
- volumes = new
- {
- master = new
- {
- level = u
- }
- }
- }));
-
- EISC.SetBoolSigAction(BoolJoin.MasterVolumeIsMuted, b =>
- PostStatusMessage(new
- {
- volumes = new
- {
- master = new
- {
- muted = b
- }
- }
- }));
-
-
- // shutdown things
- EISC.SetSigTrueAction(BoolJoin.ShutdownCancel, new Action(() =>
- PostMessage("/room/shutdown/", new
- {
- state = "wasCancelled"
- })));
- EISC.SetSigTrueAction(BoolJoin.ShutdownEnd, new Action(() =>
- PostMessage("/room/shutdown/", new
- {
- state = "hasFinished"
- })));
- EISC.SetSigTrueAction(BoolJoin.ShutdownStart, new Action(() =>
- PostMessage("/room/shutdown/", new
- {
- state = "hasStarted",
- duration = EISC.UShortOutput[UshortJoin.ShutdownPromptDuration].UShortValue
- })));
-
- // Config things
- EISC.SetSigTrueAction(BoolJoin.ConfigIsReady, LoadConfigValues);
- }
-
- ///
- /// Reads in config values when the Simpl program is ready
- ///
- void LoadConfigValues()
- {
- Debug.Console(1, this, "Loading configuration from DDVC01 EISC bridge");
- ConfigIsLoaded = false;
-
- var co = ConfigReader.ConfigObject;
-
- co.Info.RuntimeInfo.AppName = Assembly.GetExecutingAssembly().GetName().Name;
- var version = Assembly.GetExecutingAssembly().GetName().Version;
- co.Info.RuntimeInfo.AssemblyVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build);
-
-
- //Room
- if (co.Rooms == null)
- co.Rooms = new List();
- var rm = new EssentialsRoomConfig();
- if (co.Rooms.Count == 0)
- {
- Debug.Console(0, this, "Adding room to config");
- co.Rooms.Add(rm);
- }
- else
- {
- Debug.Console(0, this, "Replacing Room[0] in config");
- co.Rooms[0] = rm;
- }
- rm.Name = EISC.StringOutput[501].StringValue;
- rm.Key = "room1";
- rm.Type = "ddvc01";
-
- DDVC01RoomPropertiesConfig rmProps;
- if (rm.Properties == null)
- rmProps = new DDVC01RoomPropertiesConfig();
- else
- rmProps = JsonConvert.DeserializeObject(rm.Properties.ToString());
-
- rmProps.Help = new EssentialsHelpPropertiesConfig();
- rmProps.Help.CallButtonText = EISC.StringOutput[503].StringValue;
- rmProps.Help.Message = EISC.StringOutput[502].StringValue;
-
- rmProps.Environment = new EssentialsEnvironmentPropertiesConfig(); // enabled defaults to false
-
- rmProps.RoomPhoneNumber = EISC.StringOutput[504].StringValue;
- rmProps.RoomURI = EISC.StringOutput[505].StringValue;
- rmProps.SpeedDials = new List();
- // add speed dials as long as there are more - up to 4
- for (uint i = 512; i <= 519; i = i + 2)
- {
- var num = EISC.StringOutput[i].StringValue;
- if (string.IsNullOrEmpty(num))
- break;
- var name = EISC.StringOutput[i + 1].StringValue;
- rmProps.SpeedDials.Add(new DDVC01SpeedDial { Number = num, Name = name});
- }
- // volume control names
- var volCount = EISC.UShortOutput[701].UShortValue;
-
- //// use Volumes object or?
- //rmProps.VolumeSliderNames = new List();
- //for(uint i = 701; i <= 700 + volCount; i++)
- //{
- // rmProps.VolumeSliderNames.Add(EISC.StringInput[i].StringValue);
- //}
-
- // There should be cotija devices in here, I think...
- if(co.Devices == null)
- co.Devices = new List();
-
- // clear out previous DDVC devices
- co.Devices.RemoveAll(d => d.Key.StartsWith("source-", StringComparison.OrdinalIgnoreCase));
-
- rmProps.SourceListKey = "default";
- rm.Properties = JToken.FromObject(rmProps);
-
- // Source list! This might be brutal!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- var groupMap = GetSourceGroupDictionary();
-
- co.SourceLists = new Dictionary>();
- var newSl = new Dictionary();
- // add sources...
- for (uint i = 0; i<= 19; i++)
- {
- var name = EISC.StringOutput[601 + i].StringValue;
- if(string.IsNullOrEmpty(name))
- break;
- var icon = EISC.StringOutput[651 + i].StringValue;
- var key = EISC.StringOutput[671 + i].StringValue;
- var type = EISC.StringOutput[701 + i].StringValue;
-
- Debug.Console(0, this, "Adding source {0} '{1}'", key, name);
- var newSLI = new SourceListItem{
- Icon = icon,
- Name = name,
- Order = (int)i + 1,
- SourceKey = key,
- };
- newSl.Add(key, newSLI);
-
- string group = "genericsource";
- if (groupMap.ContainsKey(type))
- {
- group = groupMap[type];
- }
-
- // add dev to devices list
- var devConf = new DeviceConfig {
- Group = group,
- Key = key,
- Name = name,
- Type = type
- };
- co.Devices.Add(devConf);
- }
-
- co.SourceLists.Add("default", newSl);
-
- Debug.Console(0, this, "******* CONFIG FROM DDVC: \r{0}", JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented));
-
- var handler = ConfigurationIsReady;
- if (handler != null)
- {
- handler(this, new EventArgs());
- }
-
- ConfigIsLoaded = true;
- }
-
- void SendFullStatus()
- {
- if (ConfigIsLoaded)
- {
- var count = EISC.UShortOutput[801].UShortValue;
-
- Debug.Console(1, this, "The Fader Count is : {0}", count);
-
- // build volumes object, serialize and put in content of method below
-
- var auxFaders = new List();
-
- // Create auxFaders
- for (uint i = 2; i <= count; i++)
- {
- auxFaders.Add(
- new Volume(string.Format("level-{0}", i),
- EISC.UShortOutput[i].UShortValue,
- EISC.BooleanOutput[i].BoolValue,
- EISC.StringOutput[800 + i].StringValue,
- true,
- "someting.png"));
- }
-
- var volumes = new Volumes();
-
- volumes.Master = new Volume("master",
- EISC.UShortOutput[UshortJoin.MasterVolumeLevel].UShortValue,
- EISC.BooleanOutput[BoolJoin.MasterVolumeIsMuted].BoolValue,
- EISC.StringOutput[801].StringValue,
- true,
- "something.png");
-
- volumes.AuxFaders = auxFaders;
-
- PostStatusMessage(new
- {
- isOn = EISC.BooleanOutput[BoolJoin.RoomIsOn].BoolValue,
- selectedSourceKey = EISC.StringOutput[StringJoin.SelectedSourceKey].StringValue,
- volumes = volumes
- });
- }
- else
- {
- PostStatusMessage(new
- {
- error = "systemNotReady"
- });
- }
- }
-
- ///
- /// Helper for posting status message
- ///
- /// The contents of the content object
- void PostStatusMessage(object contentObject)
- {
- Parent.SendMessageToServer(JObject.FromObject(new
- {
- type = "/room/status/",
- content = contentObject
- }));
- }
-
- ///
- ///
- ///
- ///
- ///
- void PostMessage(string messageType, object contentObject)
- {
- Parent.SendMessageToServer(JObject.FromObject(new
- {
- type = messageType,
- content = contentObject
- }));
- }
-
-
- ///
- ///
- ///
- ///
- ///
- void EISC_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
- {
- if (Debug.Level >= 1)
- Debug.Console(1, this, "DDVC EISC change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
- var uo = args.Sig.UserObject;
- if (uo is Action)
- (uo as Action)(args.Sig.BoolValue);
- else if (uo is Action)
- (uo as Action)(args.Sig.UShortValue);
- else if (uo is Action)
- (uo as Action)(args.Sig.StringValue);
- }
-
- ///
- /// Returns the mapping of types to groups, for setting up devices.
- ///
- ///
- Dictionary GetSourceGroupDictionary()
- {
- //type, group
- var d = new Dictionary(StringComparer.OrdinalIgnoreCase)
- {
- { "laptop", "pc" },
- { "wireless", "genericsource" },
- { "iptv", "settopbox" }
-
- };
- return d;
- }
-
- ///
- /// updates the usercode from server
- ///
- protected override void UserCodeChange()
- {
- Debug.Console(1, this, "Server user code changed: {0}", UserCode);
- EISC.StringInput[StringJoin.UserCodeToSystem].StringValue = UserCode;
- EISC.StringInput[StringJoin.ServerUrl].StringValue = Parent.Config.ClientAppUrl;
- }
-
- ///
- ///
- ///
- ///
- ///
- void SourceChange(string oldKey, string newKey)
- {
- /* Example message
- * {
- "type":"/room/status",
- "content": {
- "selectedSourceKey": "off",
- }
- }
- */
- //if (type == ChangeType.WillChange)
- //{
- // // Disconnect from previous source
-
- // if (info != null)
- // {
- // var previousDev = info.SourceDevice;
-
- // // device type interfaces
- // if (previousDev is ISetTopBoxControls)
- // (previousDev as ISetTopBoxControls).UnlinkActions(Parent);
- // // common interfaces
- // if (previousDev is IChannel)
- // (previousDev as IChannel).UnlinkActions(Parent);
- // if (previousDev is IColor)
- // (previousDev as IColor).UnlinkActions(Parent);
- // if (previousDev is IDPad)
- // (previousDev as IDPad).UnlinkActions(Parent);
- // if (previousDev is IDvr)
- // (previousDev as IDvr).UnlinkActions(Parent);
- // if (previousDev is INumericKeypad)
- // (previousDev as INumericKeypad).UnlinkActions(Parent);
- // if (previousDev is IPower)
- // (previousDev as IPower).UnlinkActions(Parent);
- // if (previousDev is ITransport)
- // (previousDev as ITransport).UnlinkActions(Parent);
- // }
-
-
- // var huddleRoom = room as EssentialsHuddleSpaceRoom;
- // JObject roomStatus = new JObject();
- // roomStatus.Add("selectedSourceKey", huddleRoom.CurrentSourceInfoKey);
-
- // JObject message = new JObject();
-
- // message.Add("type", "/room/status/");
- // message.Add("content", roomStatus);
-
- // Parent.PostToServer(message);
- //}
- //else
- //{
- // if (info != null)
- // {
- // var dev = info.SourceDevice;
-
- // if (dev is ISetTopBoxControls)
- // (dev as ISetTopBoxControls).LinkActions(Parent);
- // if (dev is IChannel)
- // (dev as IChannel).LinkActions(Parent);
- // if (dev is IColor)
- // (dev as IColor).LinkActions(Parent);
- // if (dev is IDPad)
- // (dev as IDPad).LinkActions(Parent);
- // if (dev is IDvr)
- // (dev as IDvr).LinkActions(Parent);
- // if (dev is INumericKeypad)
- // (dev as INumericKeypad).LinkActions(Parent);
- // if (dev is IPower)
- // (dev as IPower).LinkActions(Parent);
- // if (dev is ITransport)
- // (dev as ITransport).LinkActions(Parent);
- // }
- //}
- }
- }
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharp.Reflection;
+using Crestron.SimplSharpPro.EthernetCommunication;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Config;
+using PepperDash.Essentials.Room.Config;
+
+
+namespace PepperDash.Essentials.Room.Cotija
+{
+ public class CotijaDdvc01RoomBridge : CotijaBridgeBase, IDelayedConfiguration
+ {
+ public class BoolJoin
+ {
+ ///
+ /// 301
+ ///
+ public const uint RoomIsOn = 301;
+
+ ///
+ /// 51
+ ///
+ public const uint ActivitySharePress = 51;
+ ///
+ /// 52
+ ///
+ public const uint ActivityPhoneCallPress = 52;
+ ///
+ /// 53
+ ///
+ public const uint ActivityVideoCallPress = 53;
+
+ ///
+ /// 1
+ ///
+ public const uint MasterVolumeIsMuted = 1;
+ ///
+ /// 1
+ ///
+ public const uint MasterVolumeMuteToggle = 1;
+
+ ///
+ /// 61
+ ///
+ public const uint ShutdownCancel = 61;
+ ///
+ /// 62
+ ///
+ public const uint ShutdownEnd = 62;
+ ///
+ /// 63
+ ///
+ public const uint ShutdownStart = 63;
+
+
+
+ ///
+ /// 72
+ ///
+ public const uint SourceHasChanged = 72;
+ ///
+ /// 501
+ ///
+ public const uint ConfigIsReady = 501;
+ }
+
+ public class UshortJoin
+ {
+ ///
+ /// 1
+ ///
+ public const uint MasterVolumeLevel = 1;
+
+ ///
+ /// 61
+ ///
+ public const uint ShutdownPromptDuration = 61;
+ }
+
+ public class StringJoin
+ {
+ ///
+ /// 71
+ ///
+ public const uint SelectedSourceKey = 71;
+
+ ///
+ /// 501
+ ///
+ public const uint ConfigRoomName = 501;
+ ///
+ /// 502
+ ///
+ public const uint ConfigHelpMessage = 502;
+ ///
+ /// 503
+ ///
+ public const uint ConfigHelpNumber = 503;
+ ///
+ /// 504
+ ///
+ public const uint ConfigRoomPhoneNumber = 504;
+ ///
+ /// 505
+ ///
+ public const uint ConfigRoomURI = 505;
+ ///
+ /// 401
+ ///
+ public const uint UserCodeToSystem = 401;
+ ///
+ /// 402
+ ///
+ public const uint ServerUrl = 402;
+ }
+
+ ///
+ /// Fires when config is ready to go
+ ///
+ public event EventHandler ConfigurationIsReady;
+
+ public ThreeSeriesTcpIpEthernetIntersystemCommunications EISC { get; private set; }
+
+ ///
+ ///
+ ///
+ public bool ConfigIsLoaded { get; private set; }
+
+ public override string RoomName
+ {
+ get {
+ var name = EISC.StringOutput[StringJoin.ConfigRoomName].StringValue;
+ return string.IsNullOrEmpty(name) ? "Not Loaded" : name;
+ }
+ }
+
+ CotijaDdvc01DeviceBridge SourceBridge;
+
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public CotijaDdvc01RoomBridge(string key, string name, uint ipId)
+ : base(key, name)
+ {
+ try
+ {
+ EISC = new ThreeSeriesTcpIpEthernetIntersystemCommunications(ipId, "127.0.0.2", Global.ControlSystem);
+ var reg = EISC.Register();
+ if (reg != Crestron.SimplSharpPro.eDeviceRegistrationUnRegistrationResponse.Success)
+ Debug.Console(0, this, "Cannot connect EISC at IPID {0}: \r{1}", ipId, reg);
+
+ SourceBridge = new CotijaDdvc01DeviceBridge(key + "-sourceBridge", "DDVC01 source bridge", EISC);
+ DeviceManager.AddDevice(SourceBridge);
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ }
+
+ ///
+ /// Finish wiring up everything after all devices are created. The base class will hunt down the related
+ /// parent controller and link them up.
+ ///
+ ///
+ public override bool CustomActivate()
+ {
+ Debug.Console(0, this, "Final activation. Setting up actions and feedbacks");
+ SetupFunctions();
+ SetupFeedbacks();
+
+ EISC.SigChange += EISC_SigChange;
+ EISC.OnlineStatusChange += (o, a) =>
+ {
+ Debug.Console(1, this, "DDVC EISC online={0}. Config is ready={1}", a.DeviceOnLine, EISC.BooleanOutput[BoolJoin.ConfigIsReady].BoolValue);
+ if (a.DeviceOnLine && EISC.BooleanOutput[BoolJoin.ConfigIsReady].BoolValue)
+ LoadConfigValues();
+ };
+ // load config if it's already there
+ if (EISC.IsOnline && EISC.BooleanOutput[BoolJoin.ConfigIsReady].BoolValue) // || EISC.BooleanInput[BoolJoin.ConfigIsReady].BoolValue)
+ LoadConfigValues();
+
+
+ CrestronConsole.AddNewConsoleCommand(s =>
+ {
+ for (uint i = 1; i < 1000; i++)
+ {
+ if (s.ToLower().Equals("b"))
+ {
+ CrestronConsole.ConsoleCommandResponse("D{0,6} {1} - ", i, EISC.BooleanOutput[i].BoolValue);
+ }
+ else if (s.ToLower().Equals("u"))
+ {
+ CrestronConsole.ConsoleCommandResponse("U{0,6} {1,8} - ", i, EISC.UShortOutput[i].UShortValue);
+ }
+ else if (s.ToLower().Equals("s"))
+ {
+ var val = EISC.StringOutput[i].StringValue;
+ if(!string.IsNullOrEmpty(val))
+ CrestronConsole.ConsoleCommandResponse("S{0,6} {1}\r", i, EISC.StringOutput[i].StringValue);
+ }
+
+ }
+ }, "mobilebridgedump", "Dumps DDVC01 bridge EISC data b,u,s", ConsoleAccessLevelEnum.AccessOperator);
+
+ CrestronConsole.AddNewConsoleCommand(s => LoadConfigValues(), "loadddvc", "", ConsoleAccessLevelEnum.AccessOperator);
+
+ return base.CustomActivate();
+ }
+
+
+ ///
+ /// Setup the actions to take place on various incoming API calls
+ ///
+ void SetupFunctions()
+ {
+
+ Parent.AddAction(@"/room/room1/status", new Action(SendFullStatus));
+
+ Parent.AddAction(@"/room/room1/source", new Action(c =>
+ {
+ EISC.SetString(StringJoin.SelectedSourceKey, c.SourceListItem);
+ EISC.PulseBool(BoolJoin.SourceHasChanged);
+ }));
+
+ Parent.AddAction(@"/room/room1/defaultsource", new Action(() =>
+ EISC.PulseBool(BoolJoin.ActivitySharePress)));
+
+ Parent.AddAction(@"/room/room1/volumes/master/level", new Action(u =>
+ EISC.SetUshort(UshortJoin.MasterVolumeLevel, u)));
+ Parent.AddAction(@"/room/room1/volumes/master/muteToggle", new Action(() =>
+ EISC.PulseBool(BoolJoin.MasterVolumeIsMuted)));
+
+ Parent.AddAction(@"/room/room1/shutdownStart", new Action(() =>
+ EISC.PulseBool(BoolJoin.ShutdownStart)));
+ Parent.AddAction(@"/room/room1/shutdownEnd", new Action(() =>
+ EISC.PulseBool(BoolJoin.ShutdownEnd)));
+ Parent.AddAction(@"/room/room1/shutdownCancel", new Action(() =>
+ EISC.PulseBool(BoolJoin.ShutdownCancel)));
+
+
+ // Source Device (Current Source)'
+
+ SourceDeviceMapDictionary sourceJoinMap = new SourceDeviceMapDictionary();
+
+ var prefix = @"/device/currentSource/";
+
+ foreach (var item in sourceJoinMap)
+ {
+ Parent.AddAction(string.Format("{0}{1}", prefix, item.Key), new PressAndHoldAction(b => EISC.SetBool(item.Value, b)));
+ }
+ }
+
+ ///
+ /// Links feedbacks to whatever is gonna happen!
+ ///
+ void SetupFeedbacks()
+ {
+ // Power
+ EISC.SetBoolSigAction(BoolJoin.RoomIsOn, b =>
+ PostStatusMessage(new
+ {
+ isOn = b
+ }));
+
+ // Source change things
+ EISC.SetSigTrueAction(BoolJoin.SourceHasChanged, () =>
+ PostStatusMessage(new
+ {
+ selectedSourceKey = EISC.StringOutput[StringJoin.SelectedSourceKey].StringValue
+ }));
+
+ // Volume things
+ EISC.SetUShortSigAction(UshortJoin.MasterVolumeLevel, u =>
+ PostStatusMessage(new
+ {
+ volumes = new
+ {
+ master = new
+ {
+ level = u
+ }
+ }
+ }));
+
+ EISC.SetBoolSigAction(BoolJoin.MasterVolumeIsMuted, b =>
+ PostStatusMessage(new
+ {
+ volumes = new
+ {
+ master = new
+ {
+ muted = b
+ }
+ }
+ }));
+
+
+ // shutdown things
+ EISC.SetSigTrueAction(BoolJoin.ShutdownCancel, new Action(() =>
+ PostMessage("/room/shutdown/", new
+ {
+ state = "wasCancelled"
+ })));
+ EISC.SetSigTrueAction(BoolJoin.ShutdownEnd, new Action(() =>
+ PostMessage("/room/shutdown/", new
+ {
+ state = "hasFinished"
+ })));
+ EISC.SetSigTrueAction(BoolJoin.ShutdownStart, new Action(() =>
+ PostMessage("/room/shutdown/", new
+ {
+ state = "hasStarted",
+ duration = EISC.UShortOutput[UshortJoin.ShutdownPromptDuration].UShortValue
+ })));
+
+ // Config things
+ EISC.SetSigTrueAction(BoolJoin.ConfigIsReady, LoadConfigValues);
+ }
+
+ ///
+ /// Reads in config values when the Simpl program is ready
+ ///
+ void LoadConfigValues()
+ {
+ Debug.Console(1, this, "Loading configuration from DDVC01 EISC bridge");
+ ConfigIsLoaded = false;
+
+ var co = ConfigReader.ConfigObject;
+
+ co.Info.RuntimeInfo.AppName = Assembly.GetExecutingAssembly().GetName().Name;
+ var version = Assembly.GetExecutingAssembly().GetName().Version;
+ co.Info.RuntimeInfo.AssemblyVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build);
+
+
+ //Room
+ if (co.Rooms == null)
+ co.Rooms = new List();
+ var rm = new EssentialsRoomConfig();
+ if (co.Rooms.Count == 0)
+ {
+ Debug.Console(0, this, "Adding room to config");
+ co.Rooms.Add(rm);
+ }
+ else
+ {
+ Debug.Console(0, this, "Replacing Room[0] in config");
+ co.Rooms[0] = rm;
+ }
+ rm.Name = EISC.StringOutput[501].StringValue;
+ rm.Key = "room1";
+ rm.Type = "ddvc01";
+
+ DDVC01RoomPropertiesConfig rmProps;
+ if (rm.Properties == null)
+ rmProps = new DDVC01RoomPropertiesConfig();
+ else
+ rmProps = JsonConvert.DeserializeObject(rm.Properties.ToString());
+
+ rmProps.Help = new EssentialsHelpPropertiesConfig();
+ rmProps.Help.CallButtonText = EISC.StringOutput[503].StringValue;
+ rmProps.Help.Message = EISC.StringOutput[502].StringValue;
+
+ rmProps.Environment = new EssentialsEnvironmentPropertiesConfig(); // enabled defaults to false
+
+ rmProps.RoomPhoneNumber = EISC.StringOutput[504].StringValue;
+ rmProps.RoomURI = EISC.StringOutput[505].StringValue;
+ rmProps.SpeedDials = new List();
+ // add speed dials as long as there are more - up to 4
+ for (uint i = 512; i <= 519; i = i + 2)
+ {
+ var num = EISC.StringOutput[i].StringValue;
+ if (string.IsNullOrEmpty(num))
+ break;
+ var name = EISC.StringOutput[i + 1].StringValue;
+ rmProps.SpeedDials.Add(new DDVC01SpeedDial { Number = num, Name = name});
+ }
+ // volume control names
+ var volCount = EISC.UShortOutput[701].UShortValue;
+
+ //// use Volumes object or?
+ //rmProps.VolumeSliderNames = new List();
+ //for(uint i = 701; i <= 700 + volCount; i++)
+ //{
+ // rmProps.VolumeSliderNames.Add(EISC.StringInput[i].StringValue);
+ //}
+
+ // There should be cotija devices in here, I think...
+ if(co.Devices == null)
+ co.Devices = new List();
+
+ // clear out previous DDVC devices
+ co.Devices.RemoveAll(d => d.Key.StartsWith("source-", StringComparison.OrdinalIgnoreCase));
+
+ rmProps.SourceListKey = "default";
+ rm.Properties = JToken.FromObject(rmProps);
+
+ // Source list! This might be brutal!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ var groupMap = GetSourceGroupDictionary();
+
+ co.SourceLists = new Dictionary>();
+ var newSl = new Dictionary();
+ // add sources...
+ for (uint i = 0; i<= 19; i++)
+ {
+ var name = EISC.StringOutput[601 + i].StringValue;
+ if(string.IsNullOrEmpty(name))
+ break;
+ var icon = EISC.StringOutput[651 + i].StringValue;
+ var key = EISC.StringOutput[671 + i].StringValue;
+ var type = EISC.StringOutput[701 + i].StringValue;
+
+ Debug.Console(0, this, "Adding source {0} '{1}'", key, name);
+ var newSLI = new SourceListItem{
+ Icon = icon,
+ Name = name,
+ Order = (int)i + 1,
+ SourceKey = key,
+ };
+ newSl.Add(key, newSLI);
+
+ string group = "genericsource";
+ if (groupMap.ContainsKey(type))
+ {
+ group = groupMap[type];
+ }
+
+ // add dev to devices list
+ var devConf = new DeviceConfig {
+ Group = group,
+ Key = key,
+ Name = name,
+ Type = type
+ };
+ co.Devices.Add(devConf);
+ }
+
+ co.SourceLists.Add("default", newSl);
+
+ Debug.Console(0, this, "******* CONFIG FROM DDVC: \r{0}", JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented));
+
+ var handler = ConfigurationIsReady;
+ if (handler != null)
+ {
+ handler(this, new EventArgs());
+ }
+
+ ConfigIsLoaded = true;
+ }
+
+ void SendFullStatus()
+ {
+ if (ConfigIsLoaded)
+ {
+ var count = EISC.UShortOutput[801].UShortValue;
+
+ Debug.Console(1, this, "The Fader Count is : {0}", count);
+
+ // build volumes object, serialize and put in content of method below
+
+ var auxFaders = new List();
+
+ // Create auxFaders
+ for (uint i = 2; i <= count; i++)
+ {
+ auxFaders.Add(
+ new Volume(string.Format("level-{0}", i),
+ EISC.UShortOutput[i].UShortValue,
+ EISC.BooleanOutput[i].BoolValue,
+ EISC.StringOutput[800 + i].StringValue,
+ true,
+ "someting.png"));
+ }
+
+ var volumes = new Volumes();
+
+ volumes.Master = new Volume("master",
+ EISC.UShortOutput[UshortJoin.MasterVolumeLevel].UShortValue,
+ EISC.BooleanOutput[BoolJoin.MasterVolumeIsMuted].BoolValue,
+ EISC.StringOutput[801].StringValue,
+ true,
+ "something.png");
+
+ volumes.AuxFaders = auxFaders;
+
+ PostStatusMessage(new
+ {
+ isOn = EISC.BooleanOutput[BoolJoin.RoomIsOn].BoolValue,
+ selectedSourceKey = EISC.StringOutput[StringJoin.SelectedSourceKey].StringValue,
+ volumes = volumes
+ });
+ }
+ else
+ {
+ PostStatusMessage(new
+ {
+ error = "systemNotReady"
+ });
+ }
+ }
+
+ ///
+ /// Helper for posting status message
+ ///
+ /// The contents of the content object
+ void PostStatusMessage(object contentObject)
+ {
+ Parent.SendMessageToServer(JObject.FromObject(new
+ {
+ type = "/room/status/",
+ content = contentObject
+ }));
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ void PostMessage(string messageType, object contentObject)
+ {
+ Parent.SendMessageToServer(JObject.FromObject(new
+ {
+ type = messageType,
+ content = contentObject
+ }));
+ }
+
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ void EISC_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
+ {
+ if (Debug.Level >= 1)
+ Debug.Console(1, this, "DDVC EISC change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
+ var uo = args.Sig.UserObject;
+ if (uo is Action)
+ (uo as Action)(args.Sig.BoolValue);
+ else if (uo is Action)
+ (uo as Action)(args.Sig.UShortValue);
+ else if (uo is Action)
+ (uo as Action)(args.Sig.StringValue);
+ }
+
+ ///
+ /// Returns the mapping of types to groups, for setting up devices.
+ ///
+ ///
+ Dictionary GetSourceGroupDictionary()
+ {
+ //type, group
+ var d = new Dictionary(StringComparer.OrdinalIgnoreCase)
+ {
+ { "laptop", "pc" },
+ { "wireless", "genericsource" },
+ { "iptv", "settopbox" }
+
+ };
+ return d;
+ }
+
+ ///
+ /// updates the usercode from server
+ ///
+ protected override void UserCodeChange()
+ {
+ Debug.Console(1, this, "Server user code changed: {0}", UserCode);
+ EISC.StringInput[StringJoin.UserCodeToSystem].StringValue = UserCode;
+ EISC.StringInput[StringJoin.ServerUrl].StringValue = Parent.Config.ClientAppUrl;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ void SourceChange(string oldKey, string newKey)
+ {
+ /* Example message
+ * {
+ "type":"/room/status",
+ "content": {
+ "selectedSourceKey": "off",
+ }
+ }
+ */
+ //if (type == ChangeType.WillChange)
+ //{
+ // // Disconnect from previous source
+
+ // if (info != null)
+ // {
+ // var previousDev = info.SourceDevice;
+
+ // // device type interfaces
+ // if (previousDev is ISetTopBoxControls)
+ // (previousDev as ISetTopBoxControls).UnlinkActions(Parent);
+ // // common interfaces
+ // if (previousDev is IChannel)
+ // (previousDev as IChannel).UnlinkActions(Parent);
+ // if (previousDev is IColor)
+ // (previousDev as IColor).UnlinkActions(Parent);
+ // if (previousDev is IDPad)
+ // (previousDev as IDPad).UnlinkActions(Parent);
+ // if (previousDev is IDvr)
+ // (previousDev as IDvr).UnlinkActions(Parent);
+ // if (previousDev is INumericKeypad)
+ // (previousDev as INumericKeypad).UnlinkActions(Parent);
+ // if (previousDev is IPower)
+ // (previousDev as IPower).UnlinkActions(Parent);
+ // if (previousDev is ITransport)
+ // (previousDev as ITransport).UnlinkActions(Parent);
+ // }
+
+
+ // var huddleRoom = room as EssentialsHuddleSpaceRoom;
+ // JObject roomStatus = new JObject();
+ // roomStatus.Add("selectedSourceKey", huddleRoom.CurrentSourceInfoKey);
+
+ // JObject message = new JObject();
+
+ // message.Add("type", "/room/status/");
+ // message.Add("content", roomStatus);
+
+ // Parent.PostToServer(message);
+ //}
+ //else
+ //{
+ // if (info != null)
+ // {
+ // var dev = info.SourceDevice;
+
+ // if (dev is ISetTopBoxControls)
+ // (dev as ISetTopBoxControls).LinkActions(Parent);
+ // if (dev is IChannel)
+ // (dev as IChannel).LinkActions(Parent);
+ // if (dev is IColor)
+ // (dev as IColor).LinkActions(Parent);
+ // if (dev is IDPad)
+ // (dev as IDPad).LinkActions(Parent);
+ // if (dev is IDvr)
+ // (dev as IDvr).LinkActions(Parent);
+ // if (dev is INumericKeypad)
+ // (dev as INumericKeypad).LinkActions(Parent);
+ // if (dev is IPower)
+ // (dev as IPower).LinkActions(Parent);
+ // if (dev is ITransport)
+ // (dev as ITransport).LinkActions(Parent);
+ // }
+ //}
+ }
+ }
}
\ No newline at end of file
diff --git a/PepperDashEssentials/Room/Cotija/RoomBridges/CotijaEssentialsHuddleSpaceRoomBridge.cs b/PepperDashEssentials/AppServer/RoomBridges/CotijaEssentialsHuddleSpaceRoomBridge.cs
similarity index 99%
rename from PepperDashEssentials/Room/Cotija/RoomBridges/CotijaEssentialsHuddleSpaceRoomBridge.cs
rename to PepperDashEssentials/AppServer/RoomBridges/CotijaEssentialsHuddleSpaceRoomBridge.cs
index 62176a75..8b4c1214 100644
--- a/PepperDashEssentials/Room/Cotija/RoomBridges/CotijaEssentialsHuddleSpaceRoomBridge.cs
+++ b/PepperDashEssentials/AppServer/RoomBridges/CotijaEssentialsHuddleSpaceRoomBridge.cs
@@ -160,7 +160,6 @@ namespace PepperDash.Essentials
///
void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
{
- var codec = sender as VideoCodecBase;
PostStatusMessage(new
{
calls = GetCallsMessageObject(),
diff --git a/PepperDashEssentials/Room/Cotija/RoomBridges/SourceDeviceMapDictionary.cs b/PepperDashEssentials/AppServer/RoomBridges/SourceDeviceMapDictionary.cs
similarity index 96%
rename from PepperDashEssentials/Room/Cotija/RoomBridges/SourceDeviceMapDictionary.cs
rename to PepperDashEssentials/AppServer/RoomBridges/SourceDeviceMapDictionary.cs
index 341f77dd..976c4121 100644
--- a/PepperDashEssentials/Room/Cotija/RoomBridges/SourceDeviceMapDictionary.cs
+++ b/PepperDashEssentials/AppServer/RoomBridges/SourceDeviceMapDictionary.cs
@@ -1,104 +1,104 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-
-namespace PepperDash.Essentials.Room.Cotija
-{
-
- ///
- /// Contains all of the default joins that map to API funtions
- ///
- public class SourceDeviceMapDictionary : Dictionary
- {
-
- public SourceDeviceMapDictionary(): base()
- {
- var dictionary = new Dictionary
- {
- {"preset01", 101},
- {"preset02", 102},
- {"preset03", 103},
- {"preset04", 104},
- {"preset05", 105},
- {"preset06", 106},
- {"preset07", 107},
- {"preset08", 108},
- {"preset09", 109},
- {"preset10", 110},
- {"preset11", 111},
- {"preset12", 112},
- {"preset13", 113},
- {"preset14", 114},
- {"preset15", 115},
- {"preset16", 116},
- {"preset17", 117},
- {"preset18", 118},
- {"preset19", 119},
- {"preset20", 120},
- {"preset21", 121},
- {"preset22", 122},
- {"preset23", 123},
- {"preset24", 124},
-
- {"num0", 130},
- {"num1", 131},
- {"num2", 132},
- {"num3", 133},
- {"num4", 134},
- {"num5", 135},
- {"num6", 136},
- {"num7", 137},
- {"num8", 138},
- {"num9", 139},
- {"numDash", 140},
- {"numEnter", 141},
- {"chanUp", 142},
- {"chanDown", 143},
- {"lastChan", 144},
- {"exit", 145},
- {"powerToggle", 146},
- {"red", 147},
- {"green", 148},
- {"yellow", 149},
- {"blue", 150},
- {"video", 151},
- {"previous", 152},
- {"next", 153},
- {"rewind", 154},
- {"ffwd", 155},
- {"closedCaption", 156},
- {"stop", 157},
- {"pause", 158},
- {"up", 159},
- {"down", 160},
- {"left", 161},
- {"right", 162},
- {"settings", 163},
- {"info", 164},
- {"return", 165},
- {"guide", 166},
- {"reboot", 167},
- {"dvrList", 168},
- {"replay", 169},
- {"play", 170},
- {"select", 171},
- {"record", 172},
- {"menu", 173},
- {"topMenu", 174},
- {"prevTrack", 175},
- {"nextTrack", 176},
- {"powerOn", 177},
- {"powerOff", 178},
- {"dot", 179}
-
- };
-
- foreach (var item in dictionary)
- {
- this.Add(item.Key, item.Value);
- }
- }
- }
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+
+namespace PepperDash.Essentials.Room.Cotija
+{
+
+ ///
+ /// Contains all of the default joins that map to API funtions
+ ///
+ public class SourceDeviceMapDictionary : Dictionary
+ {
+
+ public SourceDeviceMapDictionary(): base()
+ {
+ var dictionary = new Dictionary
+ {
+ {"preset01", 101},
+ {"preset02", 102},
+ {"preset03", 103},
+ {"preset04", 104},
+ {"preset05", 105},
+ {"preset06", 106},
+ {"preset07", 107},
+ {"preset08", 108},
+ {"preset09", 109},
+ {"preset10", 110},
+ {"preset11", 111},
+ {"preset12", 112},
+ {"preset13", 113},
+ {"preset14", 114},
+ {"preset15", 115},
+ {"preset16", 116},
+ {"preset17", 117},
+ {"preset18", 118},
+ {"preset19", 119},
+ {"preset20", 120},
+ {"preset21", 121},
+ {"preset22", 122},
+ {"preset23", 123},
+ {"preset24", 124},
+
+ {"num0", 130},
+ {"num1", 131},
+ {"num2", 132},
+ {"num3", 133},
+ {"num4", 134},
+ {"num5", 135},
+ {"num6", 136},
+ {"num7", 137},
+ {"num8", 138},
+ {"num9", 139},
+ {"numDash", 140},
+ {"numEnter", 141},
+ {"chanUp", 142},
+ {"chanDown", 143},
+ {"lastChan", 144},
+ {"exit", 145},
+ {"powerToggle", 146},
+ {"red", 147},
+ {"green", 148},
+ {"yellow", 149},
+ {"blue", 150},
+ {"video", 151},
+ {"previous", 152},
+ {"next", 153},
+ {"rewind", 154},
+ {"ffwd", 155},
+ {"closedCaption", 156},
+ {"stop", 157},
+ {"pause", 158},
+ {"up", 159},
+ {"down", 160},
+ {"left", 161},
+ {"right", 162},
+ {"settings", 163},
+ {"info", 164},
+ {"return", 165},
+ {"guide", 166},
+ {"reboot", 167},
+ {"dvrList", 168},
+ {"replay", 169},
+ {"play", 170},
+ {"select", 171},
+ {"record", 172},
+ {"menu", 173},
+ {"topMenu", 174},
+ {"prevTrack", 175},
+ {"nextTrack", 176},
+ {"powerOn", 177},
+ {"powerOff", 178},
+ {"dot", 179}
+
+ };
+
+ foreach (var item in dictionary)
+ {
+ this.Add(item.Key, item.Value);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/PepperDashEssentials/Room/Cotija/Volumes.cs b/PepperDashEssentials/AppServer/Volumes.cs
similarity index 100%
rename from PepperDashEssentials/Room/Cotija/Volumes.cs
rename to PepperDashEssentials/AppServer/Volumes.cs
diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj
index 3fbb485a..14e916f9 100644
--- a/PepperDashEssentials/PepperDashEssentials.csproj
+++ b/PepperDashEssentials/PepperDashEssentials.csproj
@@ -104,6 +104,7 @@
+
@@ -142,22 +143,22 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -195,7 +196,7 @@
-
+
diff --git a/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs.orig b/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs.orig
deleted file mode 100644
index 0dc8b651..00000000
--- a/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs.orig
+++ /dev/null
@@ -1,694 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using Crestron.SimplSharp;
-using Crestron.SimplSharp.CrestronIO;
-using Crestron.SimplSharp.Reflection;
-using Crestron.SimplSharpPro.CrestronThread;
-using Crestron.SimplSharp.CrestronWebSocketClient;
-using Crestron.SimplSharpPro;
-using Crestron.SimplSharp.Net.Http;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Room.Cotija;
-
-namespace PepperDash.Essentials
-{
- public class CotijaSystemController : Device
- {
- WebSocketClient WSClient;
-
- ///
- /// Prevents post operations from stomping on each other and getting lost
- ///
- CEvent PostLockEvent = new CEvent(true, true);
-
- CEvent RegisterLockEvent = new CEvent(true, true);
-
- public CotijaConfig Config { get; private set; }
-
- Dictionary ActionDictionary = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
-
- Dictionary PushedActions = new Dictionary();
-
- CTimer ServerHeartbeatCheckTimer;
-
- long ServerHeartbeatInterval = 20000;
-
- CTimer ServerReconnectTimer;
-
- long ServerReconnectInterval = 5000;
-
- string SystemUuid;
-
- List RoomBridges = new List();
-
- long ButtonHeartbeatInterval = 1000;
-
- ///
- /// Used for tracking HTTP debugging
- ///
- bool HttpDebugEnabled;
-
- ///
- ///
- ///
- ///
- ///
- ///
- public CotijaSystemController(string key, string name, CotijaConfig config) : base(key, name)
- {
- Config = config;
- Debug.Console(0, this, "Mobile UI controller initializing for server:{0}", config.ServerUrl);
-
- CrestronConsole.AddNewConsoleCommand(AuthorizeSystem,
- "mobileauth", "Authorizes system to talk to cotija server", ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(s => ShowInfo(),
- "mobileinfo", "Shows information for current mobile control session", ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(s => {
- s = s.Trim();
- if(!string.IsNullOrEmpty(s))
- {
- HttpDebugEnabled = (s.Trim() != "0");
- }
- CrestronConsole.ConsoleCommandResponse("HTTP Debug {0}", HttpDebugEnabled ? "Enabled" : "Disabled");
- },
- "mobilehttpdebug", "1 enables more verbose HTTP response debugging", ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(TestHttpRequest,
- "mobilehttprequest", "Tests an HTTP get to URL given", ConsoleAccessLevelEnum.AccessOperator);
-
- }
-
- ///
- /// Adds an action to the dictionary
- ///
- /// The path of the API command
- /// The action to be triggered by the commmand
- public void AddAction(string key, object action)
- {
- if (!ActionDictionary.ContainsKey(key))
- {
- ActionDictionary.Add(key, action);
- }
- else
- {
- Debug.Console(1, this, "Cannot add action with key '{0}' because key already exists in ActionDictionary.", key);
- }
- }
-
- ///
- /// Removes an action from the dictionary
- ///
- ///
- public void RemoveAction(string key)
- {
- if (ActionDictionary.ContainsKey(key))
- ActionDictionary.Remove(key);
- }
-
- ///
- ///
- ///
- ///
- public void AddBridge(CotijaBridgeBase bridge)
- {
- RoomBridges.Add(bridge);
- var b = bridge as IDelayedConfiguration;
- if (b != null)
- {
- Debug.Console(0, this, "Adding room bridge with delayed configuration");
- b.ConfigurationIsReady += new EventHandler(bridge_ConfigurationIsReady);
- }
- else
- {
- Debug.Console(0, this, "Adding room bridge and sending configuration");
- RegisterSystemToServer();
- }
- }
-
- ///
- ///
- ///
- ///
- ///
- void bridge_ConfigurationIsReady(object sender, EventArgs e)
- {
- Debug.Console(1, this, "Bridge ready. Registering");
- // send the configuration object to the server
- RegisterSystemToServer();
- }
-
- ///
- ///
- ///
- ///
- void ReconnectToServerTimerCallback(object o)
- {
- RegisterSystemToServer();
- }
-
- ///
- /// Verifies system connection with servers
- ///
- ///
- void AuthorizeSystem(string code)
- {
- if (string.IsNullOrEmpty(code))
- {
- CrestronConsole.ConsoleCommandResponse("Please enter a user code to authorize a system");
- return;
- }
-
- var req = new HttpClientRequest();
- string url = string.Format("http://{0}/api/system/grantcode/{1}/{2}", Config.ServerUrl, code, SystemUuid);
- Debug.Console(0, this, "Authorizing to: {0}", url);
-
- if (string.IsNullOrEmpty(Config.ServerUrl))
- {
- CrestronConsole.ConsoleCommandResponse("Config URL address is not set. Check portal configuration");
- return;
- }
- try
- {
- req.Url.Parse(url);
- new HttpClient().DispatchAsync(req, (r, e) =>
- {
- CheckHttpDebug(r, e);
- if (e == HTTP_CALLBACK_ERROR.COMPLETED)
- {
- if (r.Code == 200)
- {
- Debug.Console(0, "System authorized, sending config.");
- RegisterSystemToServer();
- }
- else if (r.Code == 404)
- {
- if (r.ContentString.Contains("codeNotFound"))
- {
- Debug.Console(0, "Authorization failed, code not found for system UUID {0}", SystemUuid);
- }
- else if (r.ContentString.Contains("uuidNotFound"))
- {
- Debug.Console(0, "Authorization failed, uuid {0} not found. Check Essentials configuration is correct",
- SystemUuid);
- }
- }
- }
- else
- Debug.Console(0, this, "Error {0} in authorizing system", e);
- });
- }
- catch (Exception e)
- {
- Debug.Console(0, this, "Error in authorizing: {0}", e);
- }
- }
-
- ///
- /// Dumps info in response to console command.
- ///
- void ShowInfo()
- {
- var url = Config != null ? Config.ServerUrl : "No config";
- string name;
- string code;
- if (RoomBridges != null && RoomBridges.Count > 0)
- {
- name = RoomBridges[0].RoomName;
- code = RoomBridges[0].UserCode;
- }
- else
- {
- name = "No config";
- code = "Not available";
- }
- var conn = WSClient == null ? "No client" : (WSClient.Connected ? "Yes" : "No");
-
- CrestronConsole.ConsoleCommandResponse(@"Mobile Control Information:
- Server address: {0}
- System Name: {1}
- System UUID: {2}
- System User code: {3}
- Connected?: {4}", url, name, SystemUuid,
- code, conn);
- }
-
- ///
- /// Registers the room with the server
- ///
- /// URL of the server, including the port number, if not 80. Format: "serverUrlOrIp:port"
- void RegisterSystemToServer()
- {
- var ready = RegisterLockEvent.Wait(20000);
- if (!ready)
- {
- Debug.Console(1, this, "RegisterSystemToServer failed to enter after 20 seconds. Ignoring");
- return;
- }
- RegisterLockEvent.Reset();
-
- try
- {
- var confObject = ConfigReader.ConfigObject;
- confObject.Info.RuntimeInfo.AppName = Assembly.GetExecutingAssembly().GetName().Name;
- var version = Assembly.GetExecutingAssembly().GetName().Version;
- confObject.Info.RuntimeInfo.AssemblyVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build);
- confObject.Info.RuntimeInfo.OsVersion = Crestron.SimplSharp.CrestronEnvironment.OSVersion.Firmware;
-
- string postBody = JsonConvert.SerializeObject(confObject);
- SystemUuid = confObject.SystemUuid;
-
- if (string.IsNullOrEmpty(postBody))
- {
- Debug.Console(1, this, "ERROR: Config body is empty. Cannot register with server.");
- }
- else
- {
- var regClient = new HttpClient();
- regClient.Verbose = true;
- regClient.KeepAlive = true;
-
- string url = string.Format("http://{0}/api/system/join/{1}", Config.ServerUrl, SystemUuid);
- Debug.Console(1, this, "Joining server at {0}", url);
-
- HttpClientRequest request = new HttpClientRequest();
- request.Url.Parse(url);
- request.RequestType = RequestType.Post;
- request.Header.SetHeaderValue("Content-Type", "application/json");
- request.ContentString = postBody;
-
- var err = regClient.DispatchAsync(request, RegistrationConnectionCallback);
- }
-
- }
- catch (Exception e)
- {
- Debug.Console(0, this, "ERROR: Initilizing Room: {0}", e);
- RegisterLockEvent.Set();
- StartReconnectTimer();
- }
-
- }
-
- ///
- /// Sends a message to the server from a room
- ///
- /// room from which the message originates
- /// object to be serialized and sent in post body
- public void SendMessageToServer(JObject o)
- {
-
- if (WSClient != null && WSClient.Connected)
- {
- string message = JsonConvert.SerializeObject(o, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
- Debug.Console(1, this, "Message TX: {0}", message);
- var messageBytes = System.Text.Encoding.UTF8.GetBytes(message);
- WSClient.Send(messageBytes, (uint)messageBytes.Length, WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__TEXT_FRAME);
- //WSClient.SendAsync(messageBytes, (uint)messageBytes.Length, WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__TEXT_FRAME);
- }
-<<<<<<< HEAD
-
-=======
-
->>>>>>> feature/ecs-684
- }
-
- ///
- /// Disconnects the SSE Client and stops the heartbeat timer
- ///
- ///
- void DisconnectStreamClient(string command)
- {
- //if(SseClient != null)
- // SseClient.Disconnect();
-
- if (WSClient != null && WSClient.Connected)
- WSClient.Disconnect();
-
- if (ServerHeartbeatCheckTimer != null)
- {
- ServerHeartbeatCheckTimer.Stop();
-
- ServerHeartbeatCheckTimer = null;
- }
- }
-
- ///
- /// The callback that fires when we get a response from our registration attempt
- ///
- ///
- ///
- void RegistrationConnectionCallback(HttpClientResponse resp, HTTP_CALLBACK_ERROR err)
- {
- CheckHttpDebug(resp, err);
- Debug.Console(1, this, "RegistrationConnectionCallback: {0}", err);
- try
- {
- if (resp != null && resp.Code == 200)
- {
- if(ServerReconnectTimer != null)
- {
- ServerReconnectTimer.Stop();
- ServerReconnectTimer = null;
- }
-
- // Success here!
- ConnectStreamClient();
- }
- else
- {
- if (resp != null)
- Debug.Console(1, this, "Response from server: {0}\n{1}", resp.Code, err);
- else
- {
- Debug.Console(1, this, "Null response received from server.");
- }
- StartReconnectTimer();
- }
- }
- catch (Exception e)
- {
- Debug.Console(1, this, "Error Initializing Stream Client: {0}", e);
- StartReconnectTimer();
- }
- RegisterLockEvent.Set();
- }
-
- ///
- /// Executes when we don't get a heartbeat message in time. Triggers reconnect.
- ///
- /// For CTimer callback. Not used
- void HeartbeatExpiredTimerCallback(object o)
- {
- Debug.Console(1, this, "Heartbeat Timer Expired.");
- if (ServerHeartbeatCheckTimer != null)
- {
- ServerHeartbeatCheckTimer.Stop();
- ServerHeartbeatCheckTimer = null;
- }
- StartReconnectTimer();
- }
-
- ///
- ///
- ///
- ///
- ///
- void StartReconnectTimer()
- {
- // Start the reconnect timer
- if (ServerReconnectTimer == null)
- {
- ServerReconnectTimer = new CTimer(ReconnectToServerTimerCallback, null, ServerReconnectInterval, ServerReconnectInterval);
- Debug.Console(1, this, "Reconnect Timer Started.");
- }
- ServerReconnectTimer.Reset(ServerReconnectInterval, ServerReconnectInterval);
- }
-
- ///
- ///
- ///
- ///
- ///
- void ResetOrStartHearbeatTimer()
- {
- if (ServerHeartbeatCheckTimer == null)
- {
- ServerHeartbeatCheckTimer = new CTimer(HeartbeatExpiredTimerCallback, null, ServerHeartbeatInterval, ServerHeartbeatInterval);
-
- Debug.Console(1, this, "Heartbeat Timer Started.");
- }
-
- ServerHeartbeatCheckTimer.Reset(ServerHeartbeatInterval, ServerHeartbeatInterval);
- }
-
-
- ///
- /// Connects the SSE Client
- ///
- ///
- void ConnectStreamClient()
- {
- Debug.Console(0, this, "Initializing Stream client to server.");
-
- if (WSClient == null)
- {
- WSClient = new WebSocketClient();
- }
- WSClient.URL = string.Format("wss://{0}/system/join/{1}", Config.ServerUrl, this.SystemUuid);
- WSClient.Connect();
- Debug.Console(0, this, "Websocket connected");
- WSClient.ReceiveCallBack = WebsocketReceiveCallback;
- //WSClient.SendCallBack = WebsocketSendCallback;
- WSClient.ReceiveAsync();
- }
-
- ///
- /// Resets reconnect timer and updates usercode
- ///
- ///
- void HandleHeartBeat(JToken content)
- {
- var code = content["userCode"];
- if(code != null)
- {
- foreach (var b in RoomBridges)
- {
- b.SetUserCode(code.Value());
- }
- }
- ResetOrStartHearbeatTimer();
- }
-
- ///
- /// Outputs debug info when enabled
- ///
- ///
- ///
- ///
- void CheckHttpDebug(HttpClientResponse r, HTTP_CALLBACK_ERROR e)
- {
- if (HttpDebugEnabled)
- {
- Debug.Console(0, this, "------ Begin HTTP Debug ---------------------------------------");
- Debug.Console(0, this, "HTTP Response URL: {0}", r.ResponseUrl.ToString());
- Debug.Console(0, this, "HTTP Response 'error' {0}", e);
- Debug.Console(0, this, "HTTP Response code: {0}", r.Code);
- Debug.Console(0, this, "HTTP Response content: \r{0}", r.ContentString);
- Debug.Console(0, this, "------ End HTTP Debug -----------------------------------------");
- }
- }
-
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- int WebsocketReceiveCallback(byte[] data, uint length, WebSocketClient.WEBSOCKET_PACKET_TYPES opcode,
- WebSocketClient.WEBSOCKET_RESULT_CODES err)
- {
- var rx = System.Text.Encoding.UTF8.GetString(data, 0, (int)length);
- if(rx.Length > 0)
- ParseStreamRx(rx);
- WSClient.ReceiveAsync();
- return 1;
- }
-
- ///
- /// Callback to catch possible errors in sending via the websocket
- ///
- ///
- ///
- int WebsocketSendCallback(Crestron.SimplSharp.CrestronWebSocketClient.WebSocketClient.WEBSOCKET_RESULT_CODES result)
- {
- Debug.Console(1, this, "SendCallback result: {0}", result);
-
- return 1;
- }
-
- ///
- ///
- ///
- ///
- ///
- void ParseStreamRx(string message)
- {
- if(string.IsNullOrEmpty(message))
- return;
-
- Debug.Console(1, this, "Message RX: '{0}'", message);
- try
- {
- var messageObj = JObject.Parse(message);
-
- var type = messageObj["type"].Value();
-
- if (type == "hello")
- {
- ResetOrStartHearbeatTimer();
- }
- else if (type == "/system/heartbeat")
- {
- HandleHeartBeat(messageObj["content"]);
- }
- else if (type == "close")
- {
- WSClient.Disconnect();
-
- ServerHeartbeatCheckTimer.Stop();
- // Start the reconnect timer
- StartReconnectTimer();
- }
- else
- {
- // Check path against Action dictionary
- if (ActionDictionary.ContainsKey(type))
- {
- var action = ActionDictionary[type];
-
- if (action is Action)
- {
- (action as Action)();
- }
- else if (action is PressAndHoldAction)
- {
- var stateString = messageObj["content"]["state"].Value();
-
- // Look for a button press event
- if (!string.IsNullOrEmpty(stateString))
- {
- switch (stateString)
- {
- case "true":
- {
- if (!PushedActions.ContainsKey(type))
- {
- PushedActions.Add(type, new CTimer(o =>
- {
- (action as PressAndHoldAction)(false);
- PushedActions.Remove(type);
- }, null, ButtonHeartbeatInterval, ButtonHeartbeatInterval));
- }
- // Maybe add an else to reset the timer
- break;
- }
- case "held":
- {
- if (!PushedActions.ContainsKey(type))
- {
- PushedActions[type].Reset(ButtonHeartbeatInterval, ButtonHeartbeatInterval);
- }
- return;
- }
- case "false":
- {
- if (PushedActions.ContainsKey(type))
- {
- PushedActions[type].Stop();
- PushedActions.Remove(type);
- }
- break;
- }
- }
-
- (action as PressAndHoldAction)(stateString == "true");
- }
- }
- else if (action is Action)
- {
- var stateString = messageObj["content"]["state"].Value();
-
- if (!string.IsNullOrEmpty(stateString))
- {
- (action as Action)(stateString == "true");
- }
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"]["value"].Value());
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"]["value"].Value());
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"]
- .ToObject());
- }
- }
- else
- {
- Debug.Console(1, this, "-- Warning: Incoming message has no registered handler");
- }
- }
- }
- catch (Exception err)
- {
- //Debug.Console(1, "SseMessageLengthBeforeFailureCount: {0}", SseMessageLengthBeforeFailureCount);
- //SseMessageLengthBeforeFailureCount = 0;
- Debug.Console(1, this, "Unable to parse message: {0}", err);
- }
- }
-
- void TestHttpRequest(string s)
- {
- {
- s = s.Trim();
- if (string.IsNullOrEmpty(s))
- {
- PrintTestHttpRequestUsage();
- return;
- }
- var tokens = s.Split(' ');
- if (tokens.Length < 2)
- {
- CrestronConsole.ConsoleCommandResponse("Too few paramaters\r");
- PrintTestHttpRequestUsage();
- return;
- }
-
- try
- {
- var url = tokens[1];
- if (tokens[0].ToLower() == "get")
- {
- var resp = new HttpClient().Get(url);
- CrestronConsole.ConsoleCommandResponse("RESPONSE:\r{0}\r\r", resp);
- }
- else if (tokens[0].ToLower() == "post")
- {
- var resp = new HttpClient().Post(url, new byte[] { });
- CrestronConsole.ConsoleCommandResponse("RESPONSE:\r{0}\r\r", resp);
- }
-
- else
- {
- CrestronConsole.ConsoleCommandResponse("Only get or post supported\r");
- PrintTestHttpRequestUsage();
- }
- }
- catch (HttpException e)
- {
- CrestronConsole.ConsoleCommandResponse("Exception in request:\r");
- CrestronConsole.ConsoleCommandResponse("Response URL: {0}\r", e.Response.ResponseUrl);
- CrestronConsole.ConsoleCommandResponse("Response Error Code: {0}\r", e.Response.Code);
- CrestronConsole.ConsoleCommandResponse("Response body: {0}\r", e.Response.ContentString);
- }
-
- }
- }
-
- void PrintTestHttpRequestUsage()
- {
- CrestronConsole.ConsoleCommandResponse("Usage: mobilehttprequest:N get/post url\r");
- }
- }
-}
\ No newline at end of file