diff --git a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IChannelExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IChannelExtensions.cs
index dd23d85a..287a9ba1 100644
--- a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IChannelExtensions.cs
+++ b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IChannelExtensions.cs
@@ -6,11 +6,11 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
public static class IChannelExtensions
{
- public static void LinkActions(this IChannel dev, CotijaSystemController controller)
+ public static void LinkActions(this IChannel dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
@@ -22,7 +22,7 @@ namespace PepperDash.Essentials.Room.Cotija
controller.AddAction(prefix + "exit", new PressAndHoldAction(dev.Exit));
}
- public static void UnlinkActions(this IChannel dev, CotijaSystemController controller)
+ public static void UnlinkActions(this IChannel dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
diff --git a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IColorExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IColorExtensions.cs
index 21296550..9912433d 100644
--- a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IColorExtensions.cs
+++ b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IColorExtensions.cs
@@ -6,11 +6,11 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
public static class IColorExtensions
{
- public static void LinkActions(this IColor dev, CotijaSystemController controller)
+ public static void LinkActions(this IColor dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
@@ -20,7 +20,7 @@ namespace PepperDash.Essentials.Room.Cotija
controller.AddAction(prefix + "blue", new PressAndHoldAction(dev.Blue));
}
- public static void UnlinkActions(this IColor dev, CotijaSystemController controller)
+ public static void UnlinkActions(this IColor dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
diff --git a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDPadExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDPadExtensions.cs
index 3652ba68..b094dfe8 100644
--- a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDPadExtensions.cs
+++ b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDPadExtensions.cs
@@ -6,11 +6,11 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
public static class IDPadExtensions
{
- public static void LinkActions(this IDPad dev, CotijaSystemController controller)
+ public static void LinkActions(this IDPad dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
@@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Room.Cotija
controller.AddAction(prefix + "exit", new PressAndHoldAction(dev.Exit));
}
- public static void UnlinkActions(this IDPad dev, CotijaSystemController controller)
+ public static void UnlinkActions(this IDPad dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
diff --git a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDvrExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDvrExtensions.cs
index 99aa1103..d4a9570b 100644
--- a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDvrExtensions.cs
+++ b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IDvrExtensions.cs
@@ -6,11 +6,11 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
public static class IDvrExtensions
{
- public static void LinkActions(this IDvr dev, CotijaSystemController controller)
+ public static void LinkActions(this IDvr dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
@@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Room.Cotija
controller.AddAction(prefix + "record", new PressAndHoldAction(dev.Record));
}
- public static void UnlinkActions(this IDvr dev, CotijaSystemController controller)
+ public static void UnlinkActions(this IDvr dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
diff --git a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/INumericExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/INumericExtensions.cs
index 376ed57b..2b61d775 100644
--- a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/INumericExtensions.cs
+++ b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/INumericExtensions.cs
@@ -6,11 +6,11 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
public static class INumericExtensions
{
- public static void LinkActions(this INumericKeypad dev, CotijaSystemController controller)
+ public static void LinkActions(this INumericKeypad dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
@@ -29,7 +29,7 @@ namespace PepperDash.Essentials.Room.Cotija
// Deal with the Accessory functions on the numpad later
}
- public static void UnlinkActions(this INumericKeypad dev, CotijaSystemController controller)
+ public static void UnlinkActions(this INumericKeypad dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
diff --git a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IPowerExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IPowerExtensions.cs
index 732d2740..515c2c7f 100644
--- a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IPowerExtensions.cs
+++ b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/IPowerExtensions.cs
@@ -6,11 +6,11 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
public static class IPowerExtensions
{
- public static void LinkActions(this IPower dev, CotijaSystemController controller)
+ public static void LinkActions(this IPower dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
@@ -19,7 +19,7 @@ namespace PepperDash.Essentials.Room.Cotija
controller.AddAction(prefix + "powerToggle", new Action(dev.PowerToggle));
}
- public static void UnlinkActions(this IPower dev, CotijaSystemController controller)
+ public static void UnlinkActions(this IPower dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
diff --git a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs
index 99198fa6..2ea60545 100644
--- a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs
+++ b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs
@@ -6,11 +6,11 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
public static class ISetTopBoxControlsExtensions
{
- public static void LinkActions(this ISetTopBoxControls dev, CotijaSystemController controller)
+ public static void LinkActions(this ISetTopBoxControls dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
@@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Room.Cotija
controller.AddAction(prefix + "replay", new PressAndHoldAction(dev.Replay));
}
- public static void UnlinkActions(this ISetTopBoxControls dev, CotijaSystemController controller)
+ public static void UnlinkActions(this ISetTopBoxControls dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
diff --git a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/ITransportExtensions.cs b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/ITransportExtensions.cs
index 9463d95f..f34fb9e3 100644
--- a/PepperDashEssentials/AppServer/DeviceTypeInterfaces/ITransportExtensions.cs
+++ b/PepperDashEssentials/AppServer/DeviceTypeInterfaces/ITransportExtensions.cs
@@ -6,11 +6,11 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
public static class ITransportExtensions
{
- public static void LinkActions(this ITransport dev, CotijaSystemController controller)
+ public static void LinkActions(this ITransport dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
@@ -24,7 +24,7 @@ namespace PepperDash.Essentials.Room.Cotija
controller.AddAction(prefix + "record", new PressAndHoldAction(dev.Record));
}
- public static void UnlinkActions(this ITransport dev, CotijaSystemController controller)
+ public static void UnlinkActions(this ITransport dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
diff --git a/PepperDashEssentials/AppServer/Interfaces.cs b/PepperDashEssentials/AppServer/Interfaces.cs
index 4372ef8a..8a1c20c8 100644
--- a/PepperDashEssentials/AppServer/Interfaces.cs
+++ b/PepperDashEssentials/AppServer/Interfaces.cs
@@ -6,7 +6,7 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
///
/// Represents a room whose configuration is derived from runtime data,
diff --git a/PepperDashEssentials/AppServer/Messengers/AudioCodecBaseMessenger.cs b/PepperDashEssentials/AppServer/Messengers/AudioCodecBaseMessenger.cs
index b37b80da..3d74b132 100644
--- a/PepperDashEssentials/AppServer/Messengers/AudioCodecBaseMessenger.cs
+++ b/PepperDashEssentials/AppServer/Messengers/AudioCodecBaseMessenger.cs
@@ -39,7 +39,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
- protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
+ protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendAtcFullMessageObject));
appServerController.AddAction(MessagePath + "/dial", new Action(s => Codec.Dial(s)));
diff --git a/PepperDashEssentials/AppServer/Messengers/ConfigMessenger.cs b/PepperDashEssentials/AppServer/Messengers/ConfigMessenger.cs
index 1e3cfa12..ae05c118 100644
--- a/PepperDashEssentials/AppServer/Messengers/ConfigMessenger.cs
+++ b/PepperDashEssentials/AppServer/Messengers/ConfigMessenger.cs
@@ -27,7 +27,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostUpdateStatus(e.UpdateStatus.ToString());
}
- protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
+ protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.AddAction(MessagePath + "/updateConfig", new Action(s => GetConfigFile(s)));
}
diff --git a/PepperDashEssentials/AppServer/Messengers/Ddvc01AtcMessenger.cs b/PepperDashEssentials/AppServer/Messengers/Ddvc01AtcMessenger.cs
index 72e2f8d3..eee94350 100644
--- a/PepperDashEssentials/AppServer/Messengers/Ddvc01AtcMessenger.cs
+++ b/PepperDashEssentials/AppServer/Messengers/Ddvc01AtcMessenger.cs
@@ -127,7 +127,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
///
///
///
- protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
+ protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
//EISC.SetStringSigAction(SCurrentDialString, s => PostStatusMessage(new { currentDialString = s }));
diff --git a/PepperDashEssentials/AppServer/Messengers/Ddvc01VtcMessenger.cs b/PepperDashEssentials/AppServer/Messengers/Ddvc01VtcMessenger.cs
index 7fb53f96..e3de11d0 100644
--- a/PepperDashEssentials/AppServer/Messengers/Ddvc01VtcMessenger.cs
+++ b/PepperDashEssentials/AppServer/Messengers/Ddvc01VtcMessenger.cs
@@ -253,7 +253,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
///
///
///
- protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
+ protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
var asc = appServerController;
EISC.SetStringSigAction(SHookState, s =>
diff --git a/PepperDashEssentials/AppServer/Messengers/MessengerBase.cs b/PepperDashEssentials/AppServer/Messengers/MessengerBase.cs
index f9833afb..d4967eee 100644
--- a/PepperDashEssentials/AppServer/Messengers/MessengerBase.cs
+++ b/PepperDashEssentials/AppServer/Messengers/MessengerBase.cs
@@ -24,7 +24,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
///
///
///
- public CotijaSystemController AppServerController { get; private set; }
+ public MobileControlSystemController AppServerController { get; private set; }
public string MessagePath { get; private set; }
@@ -47,7 +47,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// Registers this messenger with appserver controller
///
///
- public void RegisterWithAppServer(CotijaSystemController appServerController)
+ public void RegisterWithAppServer(MobileControlSystemController appServerController)
{
if (appServerController == null)
throw new ArgumentNullException("appServerController");
@@ -60,7 +60,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// Implemented in extending classes. Wire up API calls and feedback here
///
///
- abstract protected void CustomRegisterWithAppServer(CotijaSystemController appServerController);
+ abstract protected void CustomRegisterWithAppServer(MobileControlSystemController appServerController);
///
/// Helper for posting status message
diff --git a/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs b/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs
index 12107ff5..080fbd78 100644
--- a/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs
+++ b/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs
@@ -86,7 +86,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
});
}
- protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
+ protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
AppServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullStatusMessage));
}
diff --git a/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs b/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs
index 5c1c59b7..29c80085 100644
--- a/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs
+++ b/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs
@@ -160,7 +160,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// Called from base's RegisterWithAppServer method
///
///
- protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
+ protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.AddAction("/device/videoCodec/isReady", new Action(SendIsReady));
appServerController.AddAction("/device/videoCodec/fullStatus", new Action(SendVtcFullMessageObject));
diff --git a/PepperDashEssentials/AppServer/CotijaConfig.cs b/PepperDashEssentials/AppServer/MobileControlConfig.cs
similarity index 84%
rename from PepperDashEssentials/AppServer/CotijaConfig.cs
rename to PepperDashEssentials/AppServer/MobileControlConfig.cs
index 22196956..6b775a0a 100644
--- a/PepperDashEssentials/AppServer/CotijaConfig.cs
+++ b/PepperDashEssentials/AppServer/MobileControlConfig.cs
@@ -13,7 +13,7 @@ namespace PepperDash.Essentials
///
///
///
- public class CotijaConfig
+ public class MobileControlConfig
{
[JsonProperty("serverUrl")]
public string ServerUrl { get; set; }
@@ -25,7 +25,7 @@ namespace PepperDash.Essentials
///
///
///
- public class CotijaDdvc01RoomBridgePropertiesConfig
+ public class MobileControlDdvc01RoomBridgePropertiesConfig
{
[JsonProperty("eiscId")]
public string EiscId { get; set; }
diff --git a/PepperDashEssentials/AppServer/CotijaDdvc01DeviceBridge.cs b/PepperDashEssentials/AppServer/MobileControlDdvc01DeviceBridge.cs
similarity index 91%
rename from PepperDashEssentials/AppServer/CotijaDdvc01DeviceBridge.cs
rename to PepperDashEssentials/AppServer/MobileControlDdvc01DeviceBridge.cs
index 51c0bb5b..49a75263 100644
--- a/PepperDashEssentials/AppServer/CotijaDdvc01DeviceBridge.cs
+++ b/PepperDashEssentials/AppServer/MobileControlDdvc01DeviceBridge.cs
@@ -8,19 +8,19 @@ using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Essentials.Core;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
///
/// Represents a generic device connection through to and EISC for DDVC01
///
- public class CotijaDdvc01DeviceBridge : Device, IChannel, INumericKeypad
+ public class MobileControlDdvc01DeviceBridge : Device, IChannel, INumericKeypad
{
///
/// EISC used to talk to Simpl
///
ThreeSeriesTcpIpEthernetIntersystemCommunications EISC;
- public CotijaDdvc01DeviceBridge(string key, string name, ThreeSeriesTcpIpEthernetIntersystemCommunications eisc)
+ public MobileControlDdvc01DeviceBridge(string key, string name, ThreeSeriesTcpIpEthernetIntersystemCommunications eisc)
: base(key, name)
{
EISC = eisc;
diff --git a/PepperDashEssentials/AppServer/CotijaSystemController.cs b/PepperDashEssentials/AppServer/MobileControlSystemController.cs
similarity index 95%
rename from PepperDashEssentials/AppServer/CotijaSystemController.cs
rename to PepperDashEssentials/AppServer/MobileControlSystemController.cs
index 1e74efe0..08afb464 100644
--- a/PepperDashEssentials/AppServer/CotijaSystemController.cs
+++ b/PepperDashEssentials/AppServer/MobileControlSystemController.cs
@@ -1,864 +1,864 @@
-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.Core.Config;
-using PepperDash.Essentials.Room.Cotija;
-using PepperDash.Essentials.AppServer.Messengers;
-
-namespace PepperDash.Essentials
-{
- public class CotijaSystemController : Device
- {
- WebSocketClient WSClient;
-
- //bool LinkUp;
-
- ///
- /// 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();
-
- public ConfigMessenger ConfigMessenger { get; private set; }
-
- CTimer ServerHeartbeatCheckTimer;
-
- long ServerHeartbeatInterval = 20000;
-
- CTimer ServerReconnectTimer;
-
- long ServerReconnectInterval = 5000;
-
- DateTime LastAckMessage;
-
- public 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;
-
- SystemUuid = ConfigReader.ConfigObject.SystemUuid;
-
- 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);
-
- CrestronConsole.AddNewConsoleCommand(PrintActionDictionaryPaths, "mobileshowactionpaths",
- "Prints the paths in the Action Dictionary", ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(s => ConnectWebsocketClient(), "mobileconnect",
- "Forces connect of websocket", ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(s => CleanUpWebsocketClient(), "mobiledisco",
- "Disconnects websocket", ConsoleAccessLevelEnum.AccessOperator);
-
- CrestronConsole.AddNewConsoleCommand(s => ParseStreamRx(s), "mobilesimulateaction", "Simulates a message from the server", ConsoleAccessLevelEnum.AccessOperator);
-
- CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
- CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
-
- // Config Messenger
- var cmKey = Key + "-config";
- ConfigMessenger = new ConfigMessenger(cmKey, "/config");
- ConfigMessenger.RegisterWithAppServer(this);
- }
-
- ///
- /// If config rooms is empty or null then go
- ///
- ///
- public override bool CustomActivate()
- {
- if (ConfigReader.ConfigObject.Rooms == null || ConfigReader.ConfigObject.Rooms.Count == 0)
- {
- Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Config contains no rooms. Registering with Server.");
- RegisterSystemToServer();
- }
-
- return base.CustomActivate();
- }
-
- ///
- ///
- ///
- ///
- void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs args)
- {
- Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Ethernet status change, port {0}: {1}",
- args.EthernetAdapter, args.EthernetEventType);
-
- if (args.EthernetEventType == eEthernetEventType.LinkDown && WSClient != null && args.EthernetAdapter == WSClient.EthernetAdapter)
- {
- CleanUpWebsocketClient();
- }
- }
-
- ///
- /// Sends message to server to indicate the system is shutting down
- ///
- ///
- void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
- {
- if (programEventType == eProgramStatusEventType.Stopping
- && WSClient != null
- && WSClient.Connected)
- {
- CleanUpWebsocketClient();
- }
- }
-
- public void PrintActionDictionaryPaths(object o)
- {
- Debug.Console(0, this, "ActionDictionary Contents:");
-
- foreach (var item in ActionDictionary)
- {
- Debug.Console(0, this, "{0}", item.Key);
- }
- }
-
- ///
- /// 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");
- //SystemUuid = ConfigReader.ConfigObject.SystemUuid;
- RegisterSystemToServer();
- }
- }
-
- ///
- ///
- ///
- ///
- ///
- void bridge_ConfigurationIsReady(object sender, EventArgs e)
- {
- Debug.Console(1, this, "Bridge ready. Registering");
- //SystemUuid = ConfigReader.ConfigObject.SystemUuid;
- // send the configuration object to the server
- RegisterSystemToServer();
- }
-
- ///
- ///
- ///
- ///
- void ReconnectToServerTimerCallback(object o)
- {
- RegisterSystemToServer();
- }
-
- ///
- /// Verifies system connection with servers
- ///
- ///
- void AuthorizeSystem(string code)
- {
- //SystemUuid = ConfigReader.ConfigObject.SystemUuid;
-
- if (string.IsNullOrEmpty(SystemUuid))
- {
- CrestronConsole.ConsoleCommandResponse("System does not have a UUID. Please ensure proper portal-format configuration is loaded and restart.");
- return;
- }
-
- 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.");
-#warning This registration may need to wait for config ready. Maybe.
- 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");
- var secSinceLastAck = DateTime.Now - LastAckMessage;
-
-
- CrestronConsole.ConsoleCommandResponse(@"Mobile Control Information:
- Server address: {0}
- System Name: {1}
- System URL: {2}
- System UUID: {3}
- System User code: {4}
- Connected?: {5}
- Seconds Since Last Ack: {6}"
- , url, name, ConfigReader.ConfigObject.SystemUrl, SystemUuid,
- code, conn, secSinceLastAck.Seconds);
- }
-
- ///
- /// Registers the room with the server
- ///
- /// URL of the server, including the port number, if not 80. Format: "serverUrlOrIp:port"
- void RegisterSystemToServer()
- {
- ConnectWebsocketClient();
- }
-
- ///
- /// Connects the Websocket Client
- ///
- ///
- void ConnectWebsocketClient()
- {
-
- Debug.Console(1, this, "Initializing Stream client to server.");
-
- if (WSClient != null)
- {
- Debug.Console(1, this, "Cleaning up previous socket");
- CleanUpWebsocketClient();
- }
-
- WSClient = new WebSocketClient();
- WSClient.URL = string.Format("wss://{0}/system/join/{1}", Config.ServerUrl, this.SystemUuid);
- WSClient.ConnectionCallBack = Websocket_ConnectCallback;
- WSClient.ConnectAsync();
- }
-
- ///
- ///
- ///
- ///
- ///
- int Websocket_ConnectCallback(WebSocketClient.WEBSOCKET_RESULT_CODES code)
- {
- if (code == WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SUCCESS)
- {
- StopServerReconnectTimer();
- Debug.Console(1, this, "Websocket connected");
- WSClient.DisconnectCallBack = Websocket_DisconnectCallback;
- WSClient.SendCallBack = Websocket_SendCallback;
- WSClient.ReceiveCallBack = Websocket_ReceiveCallback;
- WSClient.ReceiveAsync();
- SendMessageObjectToServer(new
- {
- type = "hello"
- });
- }
- else
- {
- if (code == WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_HTTP_HANDSHAKE_TOKEN_ERROR)
- {
- // This is the case when app server is running behind a websever and app server is down
- Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Web socket connection failed. Check that app server is running behind web server");
- }
- else if (code == WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SOCKET_CONNECTION_FAILED)
- {
- // this will be the case when webserver is unreachable
- Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Web socket connection failed");
- }
- else
- {
- Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Web socket connection failure: {0}", code);
- }
- StartServerReconnectTimer();
- }
-
- return 0;
- }
-
- ///
- /// After a "hello" from the server, sends config and stuff
- ///
- void SendInitialMessage()
- {
- Debug.Console(1, this, "Sending initial join message");
- 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);
-
- var msg = new
- {
- type = "join",
- content = new
- {
- config = confObject
- }
- };
- SendMessageObjectToServer(msg);
- }
-
- ///
- /// Sends any object type to server
- ///
- ///
- public void SendMessageObjectToServer(object o)
- {
- SendMessageToServer(JObject.FromObject(o));
- }
-
- ///
- /// 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 });
-
- if (!message.Contains("/system/heartbeat"))
- Debug.Console(1, this, "Message TX: {0}", message);
- //else
- // Debug.Console(1, this, "TX messages contains /system/heartbeat");
-
- var messageBytes = System.Text.Encoding.UTF8.GetBytes(message);
- var result = WSClient.Send(messageBytes, (uint)messageBytes.Length, WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__TEXT_FRAME);
- if (result != WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SUCCESS)
- {
- Debug.Console(1, this, "Socket send result error: {0}", result);
- }
- }
- else if (WSClient == null)
- {
- Debug.Console(1, this, "Cannot send. Not connected.");
- }
- }
-
- ///
- /// Disconnects the SSE Client and stops the heartbeat timer
- ///
- ///
- void CleanUpWebsocketClient()
- {
- Debug.Console(1, this, "Disconnecting websocket");
- if (WSClient != null)
- {
- WSClient.SendCallBack = null;
- WSClient.ReceiveCallBack = null;
- WSClient.ConnectionCallBack = null;
- WSClient.DisconnectCallBack = null;
- if (WSClient.Connected)
- {
- WSClient.Disconnect();
- }
- WSClient = null;
- }
- }
-
- ///
- ///
- ///
- ///
- ///
- void StartServerReconnectTimer()
- {
- StopServerReconnectTimer();
- ServerReconnectTimer = new CTimer(ReconnectToServerTimerCallback, ServerReconnectInterval);
- Debug.Console(1, this, "Reconnect Timer Started.");
- }
-
- ///
- /// Does what it says
- ///
- void StopServerReconnectTimer()
- {
- if (ServerReconnectTimer != null)
- {
- ServerReconnectTimer.Stop();
- ServerReconnectTimer = null;
- }
- }
-
- ///
- /// 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;
- }
- CleanUpWebsocketClient();
- StartServerReconnectTimer();
- }
-
- ///
- ///
- ///
- ///
- ///
- void ResetOrStartHearbeatTimer()
- {
- if (ServerHeartbeatCheckTimer == null)
- {
- ServerHeartbeatCheckTimer = new CTimer(HeartbeatExpiredTimerCallback, null, ServerHeartbeatInterval, ServerHeartbeatInterval);
- Debug.Console(1, this, "Heartbeat Timer Started.");
- }
- else
- {
- ServerHeartbeatCheckTimer.Reset(ServerHeartbeatInterval, ServerHeartbeatInterval);
- }
- }
-
- ///
- /// Waits two and goes again
- ///
- void ReconnectStreamClient()
- {
- new CTimer(o => ConnectWebsocketClient(), 2000);
- }
-
- ///
- ///
- ///
- ///
- ///
- int Websocket_DisconnectCallback(WebSocketClient.WEBSOCKET_RESULT_CODES code, object o)
- {
- Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Websocket disconnected with code: {0}", code);
-
- if (ServerHeartbeatCheckTimer != null)
- ServerHeartbeatCheckTimer.Stop();
- // Start the reconnect timer
- StartServerReconnectTimer();
- return 0;
- }
-
-
- ///
- /// Resets reconnect timer and updates usercode
- ///
- ///
- void HandleHeartBeat(JToken content)
- {
- SendMessageToServer(JObject.FromObject(new
- {
- type = "/system/heartbeatAck"
- }));
-
- 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)
- {
- try
- {
- Debug.Console(0, this, "------ Begin HTTP Debug ---------------------------------------");
- if (r != null)
- {
- Debug.Console(0, this, "HTTP Response URL: {0}", r.ResponseUrl != null ? r.ResponseUrl.ToString() : "NONE");
- Debug.Console(0, this, "HTTP Response code: {0}", r.Code);
- Debug.Console(0, this, "HTTP Response content: \r{0}", r.ContentString);
- }
- else
- {
- Debug.Console(0, this, "No HTTP response");
- }
- Debug.Console(0, this, "HTTP Response 'error' {0}", e);
- Debug.Console(0, this, "------ End HTTP Debug -----------------------------------------");
- }
- catch (Exception ex)
- {
- Debug.Console(0, this, "HttpDebugError: {0}", ex);
- }
- }
- }
-
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- int Websocket_ReceiveCallback(byte[] data, uint length, WebSocketClient.WEBSOCKET_PACKET_TYPES opcode,
- WebSocketClient.WEBSOCKET_RESULT_CODES err)
- {
- if (opcode == WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__TEXT_FRAME)
- {
- var rx = System.Text.Encoding.UTF8.GetString(data, 0, (int)length);
- if (rx.Length > 0)
- ParseStreamRx(rx);
- WSClient.ReceiveAsync();
- }
-
- else if (opcode == WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__CLOSE)
- {
- Debug.Console(1, this, "Websocket disconnect received from remote");
- CleanUpWebsocketClient();
- }
- else
- {
- Debug.Console(1, this, "websocket rx opcode/err {0}/{1}", opcode, err);
- WSClient.ReceiveAsync();
- }
- return 0;
- }
-
- ///
- /// Callback to catch possible errors in sending via the websocket
- ///
- ///
- ///
- int Websocket_SendCallback(Crestron.SimplSharp.CrestronWebSocketClient.WebSocketClient.WEBSOCKET_RESULT_CODES result)
- {
- if(result != WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SUCCESS)
- Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SendCallback questionable result: {0}", result);
- return 1;
- }
-
- ///
- ///
- ///
- ///
- ///
- void ParseStreamRx(string message)
- {
- if(string.IsNullOrEmpty(message))
- return;
-
- if (!message.Contains("/system/heartbeat"))
- {
- Debug.Console(1, this, "Message RX: {0}", message);
- }
- else
- {
- LastAckMessage = DateTime.Now;
- }
-
- try
- {
- var messageObj = JObject.Parse(message);
-
- var type = messageObj["type"].Value();
-
- if (type == "hello")
- {
- SendInitialMessage();
- ResetOrStartHearbeatTimer();
- }
- else if (type == "/system/heartbeat")
- {
- HandleHeartBeat(messageObj["content"]);
- }
- else if (type == "raw")
- {
- var wrapper = messageObj["content"].ToObject();
- DeviceJsonApi.DoDeviceAction(wrapper);
- }
- else if (type == "close")
- {
- Debug.Console(1, this, "Received close message from server.");
- // DisconnectWebsocketClient();
-
- if (ServerHeartbeatCheckTimer != null)
- ServerHeartbeatCheckTimer.Stop();
- }
- 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");
- }
- }
+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.Core.Config;
+using PepperDash.Essentials.Room.MobileControl;
+using PepperDash.Essentials.AppServer.Messengers;
+
+namespace PepperDash.Essentials
+{
+ public class MobileControlSystemController : Device
+ {
+ WebSocketClient WSClient;
+
+ //bool LinkUp;
+
+ ///
+ /// Prevents post operations from stomping on each other and getting lost
+ ///
+ CEvent PostLockEvent = new CEvent(true, true);
+
+ CEvent RegisterLockEvent = new CEvent(true, true);
+
+ public MobileControlConfig Config { get; private set; }
+
+ Dictionary ActionDictionary = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
+
+ Dictionary PushedActions = new Dictionary();
+
+ public ConfigMessenger ConfigMessenger { get; private set; }
+
+ CTimer ServerHeartbeatCheckTimer;
+
+ long ServerHeartbeatInterval = 20000;
+
+ CTimer ServerReconnectTimer;
+
+ long ServerReconnectInterval = 5000;
+
+ DateTime LastAckMessage;
+
+ public string SystemUuid;
+
+ List RoomBridges = new List();
+
+ long ButtonHeartbeatInterval = 1000;
+
+ ///
+ /// Used for tracking HTTP debugging
+ ///
+ bool HttpDebugEnabled;
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public MobileControlSystemController(string key, string name, MobileControlConfig config) : base(key, name)
+ {
+ Config = config;
+
+ SystemUuid = ConfigReader.ConfigObject.SystemUuid;
+
+ Debug.Console(0, this, "Mobile UI controller initializing for server:{0}", config.ServerUrl);
+
+ CrestronConsole.AddNewConsoleCommand(AuthorizeSystem,
+ "mobileauth", "Authorizes system to talk to Mobile Control 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);
+
+ CrestronConsole.AddNewConsoleCommand(PrintActionDictionaryPaths, "mobileshowactionpaths",
+ "Prints the paths in the Action Dictionary", ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.AddNewConsoleCommand(s => ConnectWebsocketClient(), "mobileconnect",
+ "Forces connect of websocket", ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.AddNewConsoleCommand(s => CleanUpWebsocketClient(), "mobiledisco",
+ "Disconnects websocket", ConsoleAccessLevelEnum.AccessOperator);
+
+ CrestronConsole.AddNewConsoleCommand(s => ParseStreamRx(s), "mobilesimulateaction", "Simulates a message from the server", ConsoleAccessLevelEnum.AccessOperator);
+
+ CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
+ CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
+
+ // Config Messenger
+ var cmKey = Key + "-config";
+ ConfigMessenger = new ConfigMessenger(cmKey, "/config");
+ ConfigMessenger.RegisterWithAppServer(this);
+ }
+
+ ///
+ /// If config rooms is empty or null then go
+ ///
+ ///
+ public override bool CustomActivate()
+ {
+ if (ConfigReader.ConfigObject.Rooms == null || ConfigReader.ConfigObject.Rooms.Count == 0)
+ {
+ Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Config contains no rooms. Registering with Server.");
+ RegisterSystemToServer();
+ }
+
+ return base.CustomActivate();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs args)
+ {
+ Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Ethernet status change, port {0}: {1}",
+ args.EthernetAdapter, args.EthernetEventType);
+
+ if (args.EthernetEventType == eEthernetEventType.LinkDown && WSClient != null && args.EthernetAdapter == WSClient.EthernetAdapter)
+ {
+ CleanUpWebsocketClient();
+ }
+ }
+
+ ///
+ /// Sends message to server to indicate the system is shutting down
+ ///
+ ///
+ void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
+ {
+ if (programEventType == eProgramStatusEventType.Stopping
+ && WSClient != null
+ && WSClient.Connected)
+ {
+ CleanUpWebsocketClient();
+ }
+ }
+
+ public void PrintActionDictionaryPaths(object o)
+ {
+ Debug.Console(0, this, "ActionDictionary Contents:");
+
+ foreach (var item in ActionDictionary)
+ {
+ Debug.Console(0, this, "{0}", item.Key);
+ }
+ }
+
+ ///
+ /// 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(MobileControlBridgeBase 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");
+ //SystemUuid = ConfigReader.ConfigObject.SystemUuid;
+ RegisterSystemToServer();
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ void bridge_ConfigurationIsReady(object sender, EventArgs e)
+ {
+ Debug.Console(1, this, "Bridge ready. Registering");
+ //SystemUuid = ConfigReader.ConfigObject.SystemUuid;
+ // send the configuration object to the server
+ RegisterSystemToServer();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ void ReconnectToServerTimerCallback(object o)
+ {
+ RegisterSystemToServer();
+ }
+
+ ///
+ /// Verifies system connection with servers
+ ///
+ ///
+ void AuthorizeSystem(string code)
+ {
+ //SystemUuid = ConfigReader.ConfigObject.SystemUuid;
+
+ if (string.IsNullOrEmpty(SystemUuid))
+ {
+ CrestronConsole.ConsoleCommandResponse("System does not have a UUID. Please ensure proper portal-format configuration is loaded and restart.");
+ return;
+ }
+
+ 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.");
+#warning This registration may need to wait for config ready. Maybe.
+ 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");
+ var secSinceLastAck = DateTime.Now - LastAckMessage;
+
+
+ CrestronConsole.ConsoleCommandResponse(@"Mobile Control Information:
+ Server address: {0}
+ System Name: {1}
+ System URL: {2}
+ System UUID: {3}
+ System User code: {4}
+ Connected?: {5}
+ Seconds Since Last Ack: {6}"
+ , url, name, ConfigReader.ConfigObject.SystemUrl, SystemUuid,
+ code, conn, secSinceLastAck.Seconds);
+ }
+
+ ///
+ /// Registers the room with the server
+ ///
+ /// URL of the server, including the port number, if not 80. Format: "serverUrlOrIp:port"
+ void RegisterSystemToServer()
+ {
+ ConnectWebsocketClient();
+ }
+
+ ///
+ /// Connects the Websocket Client
+ ///
+ ///
+ void ConnectWebsocketClient()
+ {
+
+ Debug.Console(1, this, "Initializing Stream client to server.");
+
+ if (WSClient != null)
+ {
+ Debug.Console(1, this, "Cleaning up previous socket");
+ CleanUpWebsocketClient();
+ }
+
+ WSClient = new WebSocketClient();
+ WSClient.URL = string.Format("wss://{0}/system/join/{1}", Config.ServerUrl, this.SystemUuid);
+ WSClient.ConnectionCallBack = Websocket_ConnectCallback;
+ WSClient.ConnectAsync();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ int Websocket_ConnectCallback(WebSocketClient.WEBSOCKET_RESULT_CODES code)
+ {
+ if (code == WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SUCCESS)
+ {
+ StopServerReconnectTimer();
+ Debug.Console(1, this, "Websocket connected");
+ WSClient.DisconnectCallBack = Websocket_DisconnectCallback;
+ WSClient.SendCallBack = Websocket_SendCallback;
+ WSClient.ReceiveCallBack = Websocket_ReceiveCallback;
+ WSClient.ReceiveAsync();
+ SendMessageObjectToServer(new
+ {
+ type = "hello"
+ });
+ }
+ else
+ {
+ if (code == WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_HTTP_HANDSHAKE_TOKEN_ERROR)
+ {
+ // This is the case when app server is running behind a websever and app server is down
+ Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Web socket connection failed. Check that app server is running behind web server");
+ }
+ else if (code == WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SOCKET_CONNECTION_FAILED)
+ {
+ // this will be the case when webserver is unreachable
+ Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Web socket connection failed");
+ }
+ else
+ {
+ Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Web socket connection failure: {0}", code);
+ }
+ StartServerReconnectTimer();
+ }
+
+ return 0;
+ }
+
+ ///
+ /// After a "hello" from the server, sends config and stuff
+ ///
+ void SendInitialMessage()
+ {
+ Debug.Console(1, this, "Sending initial join message");
+ 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);
+
+ var msg = new
+ {
+ type = "join",
+ content = new
+ {
+ config = confObject
+ }
+ };
+ SendMessageObjectToServer(msg);
+ }
+
+ ///
+ /// Sends any object type to server
+ ///
+ ///
+ public void SendMessageObjectToServer(object o)
+ {
+ SendMessageToServer(JObject.FromObject(o));
+ }
+
+ ///
+ /// 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 });
+
+ if (!message.Contains("/system/heartbeat"))
+ Debug.Console(1, this, "Message TX: {0}", message);
+ //else
+ // Debug.Console(1, this, "TX messages contains /system/heartbeat");
+
+ var messageBytes = System.Text.Encoding.UTF8.GetBytes(message);
+ var result = WSClient.Send(messageBytes, (uint)messageBytes.Length, WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__TEXT_FRAME);
+ if (result != WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SUCCESS)
+ {
+ Debug.Console(1, this, "Socket send result error: {0}", result);
+ }
+ }
+ else if (WSClient == null)
+ {
+ Debug.Console(1, this, "Cannot send. Not connected.");
+ }
+ }
+
+ ///
+ /// Disconnects the SSE Client and stops the heartbeat timer
+ ///
+ ///
+ void CleanUpWebsocketClient()
+ {
+ Debug.Console(1, this, "Disconnecting websocket");
+ if (WSClient != null)
+ {
+ WSClient.SendCallBack = null;
+ WSClient.ReceiveCallBack = null;
+ WSClient.ConnectionCallBack = null;
+ WSClient.DisconnectCallBack = null;
+ if (WSClient.Connected)
+ {
+ WSClient.Disconnect();
+ }
+ WSClient = null;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ void StartServerReconnectTimer()
+ {
+ StopServerReconnectTimer();
+ ServerReconnectTimer = new CTimer(ReconnectToServerTimerCallback, ServerReconnectInterval);
+ Debug.Console(1, this, "Reconnect Timer Started.");
+ }
+
+ ///
+ /// Does what it says
+ ///
+ void StopServerReconnectTimer()
+ {
+ if (ServerReconnectTimer != null)
+ {
+ ServerReconnectTimer.Stop();
+ ServerReconnectTimer = null;
+ }
+ }
+
+ ///
+ /// 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;
+ }
+ CleanUpWebsocketClient();
+ StartServerReconnectTimer();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ void ResetOrStartHearbeatTimer()
+ {
+ if (ServerHeartbeatCheckTimer == null)
+ {
+ ServerHeartbeatCheckTimer = new CTimer(HeartbeatExpiredTimerCallback, null, ServerHeartbeatInterval, ServerHeartbeatInterval);
+ Debug.Console(1, this, "Heartbeat Timer Started.");
+ }
+ else
+ {
+ ServerHeartbeatCheckTimer.Reset(ServerHeartbeatInterval, ServerHeartbeatInterval);
+ }
+ }
+
+ ///
+ /// Waits two and goes again
+ ///
+ void ReconnectStreamClient()
+ {
+ new CTimer(o => ConnectWebsocketClient(), 2000);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ int Websocket_DisconnectCallback(WebSocketClient.WEBSOCKET_RESULT_CODES code, object o)
+ {
+ Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Websocket disconnected with code: {0}", code);
+
+ if (ServerHeartbeatCheckTimer != null)
+ ServerHeartbeatCheckTimer.Stop();
+ // Start the reconnect timer
+ StartServerReconnectTimer();
+ return 0;
+ }
+
+
+ ///
+ /// Resets reconnect timer and updates usercode
+ ///
+ ///
+ void HandleHeartBeat(JToken content)
+ {
+ SendMessageToServer(JObject.FromObject(new
+ {
+ type = "/system/heartbeatAck"
+ }));
+
+ 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)
+ {
+ try
+ {
+ Debug.Console(0, this, "------ Begin HTTP Debug ---------------------------------------");
+ if (r != null)
+ {
+ Debug.Console(0, this, "HTTP Response URL: {0}", r.ResponseUrl != null ? r.ResponseUrl.ToString() : "NONE");
+ Debug.Console(0, this, "HTTP Response code: {0}", r.Code);
+ Debug.Console(0, this, "HTTP Response content: \r{0}", r.ContentString);
+ }
+ else
+ {
+ Debug.Console(0, this, "No HTTP response");
+ }
+ Debug.Console(0, this, "HTTP Response 'error' {0}", e);
+ Debug.Console(0, this, "------ End HTTP Debug -----------------------------------------");
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(0, this, "HttpDebugError: {0}", ex);
+ }
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ int Websocket_ReceiveCallback(byte[] data, uint length, WebSocketClient.WEBSOCKET_PACKET_TYPES opcode,
+ WebSocketClient.WEBSOCKET_RESULT_CODES err)
+ {
+ if (opcode == WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__TEXT_FRAME)
+ {
+ var rx = System.Text.Encoding.UTF8.GetString(data, 0, (int)length);
+ if (rx.Length > 0)
+ ParseStreamRx(rx);
+ WSClient.ReceiveAsync();
+ }
+
+ else if (opcode == WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__CLOSE)
+ {
+ Debug.Console(1, this, "Websocket disconnect received from remote");
+ CleanUpWebsocketClient();
+ }
+ else
+ {
+ Debug.Console(1, this, "websocket rx opcode/err {0}/{1}", opcode, err);
+ WSClient.ReceiveAsync();
+ }
+ return 0;
+ }
+
+ ///
+ /// Callback to catch possible errors in sending via the websocket
+ ///
+ ///
+ ///
+ int Websocket_SendCallback(Crestron.SimplSharp.CrestronWebSocketClient.WebSocketClient.WEBSOCKET_RESULT_CODES result)
+ {
+ if(result != WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SUCCESS)
+ Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SendCallback questionable result: {0}", result);
+ return 1;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ void ParseStreamRx(string message)
+ {
+ if(string.IsNullOrEmpty(message))
+ return;
+
+ if (!message.Contains("/system/heartbeat"))
+ {
+ Debug.Console(1, this, "Message RX: {0}", message);
+ }
+ else
+ {
+ LastAckMessage = DateTime.Now;
+ }
+
+ try
+ {
+ var messageObj = JObject.Parse(message);
+
+ var type = messageObj["type"].Value();
+
+ if (type == "hello")
+ {
+ SendInitialMessage();
+ ResetOrStartHearbeatTimer();
+ }
+ else if (type == "/system/heartbeat")
+ {
+ HandleHeartBeat(messageObj["content"]);
+ }
+ else if (type == "raw")
+ {
+ var wrapper = messageObj["content"].ToObject();
+ DeviceJsonApi.DoDeviceAction(wrapper);
+ }
+ else if (type == "close")
+ {
+ Debug.Console(1, this, "Received close message from server.");
+ // DisconnectWebsocketClient();
+
+ if (ServerHeartbeatCheckTimer != null)
+ ServerHeartbeatCheckTimer.Stop();
+ }
+ 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
diff --git a/PepperDashEssentials/AppServer/RoomBridges/CotijaBridgeBase.cs b/PepperDashEssentials/AppServer/RoomBridges/MobileControlBridgeBase.cs
similarity index 81%
rename from PepperDashEssentials/AppServer/RoomBridges/CotijaBridgeBase.cs
rename to PepperDashEssentials/AppServer/RoomBridges/MobileControlBridgeBase.cs
index a578a0ae..d7258070 100644
--- a/PepperDashEssentials/AppServer/RoomBridges/CotijaBridgeBase.cs
+++ b/PepperDashEssentials/AppServer/RoomBridges/MobileControlBridgeBase.cs
@@ -12,15 +12,15 @@ namespace PepperDash.Essentials
///
///
///
- public abstract class CotijaBridgeBase: Device
+ public abstract class MobileControlBridgeBase: Device
{
- public CotijaSystemController Parent { get; private set; }
+ public MobileControlSystemController Parent { get; private set; }
public string UserCode { get; private set; }
public abstract string RoomName { get; }
- public CotijaBridgeBase(string key, string name)
+ public MobileControlBridgeBase(string key, string name)
: base(key, name)
{
}
@@ -30,7 +30,7 @@ namespace PepperDash.Essentials
/// as adding actions to parent
///
///
- public virtual void AddParent(CotijaSystemController parent)
+ public virtual void AddParent(MobileControlSystemController parent)
{
Parent = parent;
}
diff --git a/PepperDashEssentials/AppServer/RoomBridges/CotijaDdvc01RoomBridge.cs b/PepperDashEssentials/AppServer/RoomBridges/MobileControlDdvc01RoomBridge.cs
similarity index 98%
rename from PepperDashEssentials/AppServer/RoomBridges/CotijaDdvc01RoomBridge.cs
rename to PepperDashEssentials/AppServer/RoomBridges/MobileControlDdvc01RoomBridge.cs
index 0ff3c80c..eefd8fbc 100644
--- a/PepperDashEssentials/AppServer/RoomBridges/CotijaDdvc01RoomBridge.cs
+++ b/PepperDashEssentials/AppServer/RoomBridges/MobileControlDdvc01RoomBridge.cs
@@ -16,9 +16,9 @@ using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.Config;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
- public class CotijaDdvc01RoomBridge : CotijaBridgeBase, IDelayedConfiguration
+ public class MobileControlDdvc01RoomBridge : MobileControlBridgeBase, IDelayedConfiguration
{
public class BoolJoin
{
@@ -236,7 +236,7 @@ namespace PepperDash.Essentials.Room.Cotija
}
}
- CotijaDdvc01DeviceBridge SourceBridge;
+ MobileControlDdvc01DeviceBridge SourceBridge;
Ddvc01AtcMessenger AtcMessenger;
Ddvc01VtcMessenger VtcMessenger;
@@ -248,7 +248,7 @@ namespace PepperDash.Essentials.Room.Cotija
///
///
///
- public CotijaDdvc01RoomBridge(string key, string name, uint ipId)
+ public MobileControlDdvc01RoomBridge(string key, string name, uint ipId)
: base(key, name)
{
try
@@ -258,7 +258,7 @@ namespace PepperDash.Essentials.Room.Cotija
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);
+ SourceBridge = new MobileControlDdvc01DeviceBridge(key + "-sourceBridge", "DDVC01 source bridge", EISC);
DeviceManager.AddDevice(SourceBridge);
}
catch (Exception)
@@ -590,7 +590,7 @@ namespace PepperDash.Essentials.Room.Cotija
// rmProps.VolumeSliderNames.Add(EISC.StringInput[i].StringValue);
//}
- // There should be cotija devices in here, I think...
+ // There should be Mobile Control devices in here, I think...
if(co.Devices == null)
co.Devices = new List();
diff --git a/PepperDashEssentials/AppServer/RoomBridges/CotijaEssentialsHuddleSpaceRoomBridge.cs b/PepperDashEssentials/AppServer/RoomBridges/MobileControlEssentialsHuddleSpaceRoomBridge.cs
similarity index 87%
rename from PepperDashEssentials/AppServer/RoomBridges/CotijaEssentialsHuddleSpaceRoomBridge.cs
rename to PepperDashEssentials/AppServer/RoomBridges/MobileControlEssentialsHuddleSpaceRoomBridge.cs
index a55dbdee..fd36389a 100644
--- a/PepperDashEssentials/AppServer/RoomBridges/CotijaEssentialsHuddleSpaceRoomBridge.cs
+++ b/PepperDashEssentials/AppServer/RoomBridges/MobileControlEssentialsHuddleSpaceRoomBridge.cs
@@ -9,14 +9,14 @@ using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.AppServer.Messengers;
using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Room.Cotija;
+using PepperDash.Essentials.Room.MobileControl;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
namespace PepperDash.Essentials
{
- public class CotijaEssentialsHuddleSpaceRoomBridge : CotijaBridgeBase
+ public class MobileConrolEssentialsHuddleSpaceRoomBridge : MobileControlBridgeBase
{
public EssentialsRoomBase Room { get; private set; }
@@ -42,7 +42,7 @@ namespace PepperDash.Essentials
///
///
///
- public CotijaEssentialsHuddleSpaceRoomBridge(EssentialsRoomBase room):
+ public MobileConrolEssentialsHuddleSpaceRoomBridge(EssentialsRoomBase room):
base("mobileControlBridge-essentialsHuddle", "Essentials Mobile Control Bridge-Huddle")
{
Room = room;
@@ -52,7 +52,7 @@ namespace PepperDash.Essentials
/// Override of base: calls base to add parent and then registers actions and events.
///
///
- public override void AddParent(CotijaSystemController parent)
+ public override void AddParent(MobileControlSystemController parent)
{
base.AddParent(parent);
@@ -169,19 +169,6 @@ namespace PepperDash.Essentials
});
}
- /////
- ///// Handler for codec changes
- /////
- //void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
- //{
- // PostStatusMessage(new
- // {
- // calls = GetCallsMessageObject(),
- // //vtc = GetVtcCallsMessageObject()
- // });
-
- //}
-
///
/// Helper for posting status message
///
@@ -435,45 +422,6 @@ namespace PepperDash.Essentials
volumes = volumes
});
}
-
- /////
- ///// Helper to return a anonymous object with the call data for JSON message
- /////
- /////
- //object GetCallsMessageObject()
- //{
- // var callRm = Room as IHasVideoCodec;
- // if (callRm == null)
- // return null;
- // return new
- // {
- // activeCalls = callRm.VideoCodec.ActiveCalls,
- // callType = callRm.CallTypeFeedback.IntValue,
- // inCall = callRm.InCallFeedback.BoolValue,
- // isSharing = callRm.IsSharingFeedback.BoolValue,
- // privacyModeIsOn = callRm.PrivacyModeIsOnFeedback.BoolValue
- // };
- //}
-
- /////
- ///// Helper method to build call status for vtc
- /////
- /////
- //object GetVtcCallsMessageObject()
- //{
- // var callRm = Room as IHasVideoCodec;
- // object vtc = null;
- // if (callRm != null)
- // {
- // var codec = callRm.VideoCodec;
- // vtc = new
- // {
- // isInCall = codec.IsInCall,
- // calls = codec.ActiveCalls
- // };
- // }
- // return vtc;
- //}
}
///
diff --git a/PepperDashEssentials/AppServer/RoomBridges/SourceDeviceMapDictionary.cs b/PepperDashEssentials/AppServer/RoomBridges/SourceDeviceMapDictionary.cs
index 976c4121..b025de44 100644
--- a/PepperDashEssentials/AppServer/RoomBridges/SourceDeviceMapDictionary.cs
+++ b/PepperDashEssentials/AppServer/RoomBridges/SourceDeviceMapDictionary.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using Crestron.SimplSharp;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
///
diff --git a/PepperDashEssentials/AppServer/Volumes.cs b/PepperDashEssentials/AppServer/Volumes.cs
index 5806f117..5b5096b0 100644
--- a/PepperDashEssentials/AppServer/Volumes.cs
+++ b/PepperDashEssentials/AppServer/Volumes.cs
@@ -6,7 +6,7 @@ using Crestron.SimplSharp;
using Newtonsoft.Json;
-namespace PepperDash.Essentials.Room.Cotija
+namespace PepperDash.Essentials.Room.MobileControl
{
public class Volumes
{
diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs
index 151509f2..c080c1b2 100644
--- a/PepperDashEssentials/ControlSystem.cs
+++ b/PepperDashEssentials/ControlSystem.cs
@@ -15,7 +15,7 @@ using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
using PepperDash.Essentials.Room.Config;
-using PepperDash.Essentials.Room.Cotija;
+using PepperDash.Essentials.Room.MobileControl;
namespace PepperDash.Essentials
{
@@ -40,8 +40,11 @@ namespace PepperDash.Essentials
{
DeterminePlatform();
- //CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
- // ConsoleAccessLevelEnum.AccessOperator);
+ //if (Debug.DoNotLoadOnNextBoot)
+ //{
+ // CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
+ // ConsoleAccessLevelEnum.AccessOperator);
+ //}
// CrestronConsole.AddNewConsoleCommand(S => { ConfigWriter.WriteConfigFile(null); }, "writeconfig", "writes the current config to a file", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
@@ -71,7 +74,8 @@ namespace PepperDash.Essentials
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
- GoWithLoad();
+ //if(!Debug.DoNotLoadOnNextBoot)
+ GoWithLoad();
}
///
@@ -81,57 +85,64 @@ namespace PepperDash.Essentials
///
public void DeterminePlatform()
{
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Determining Platform....");
-
- string filePathPrefix;
-
- var dirSeparator = Global.DirectorySeparator;
-
- var version = Crestron.SimplSharp.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
-
- var versionString = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build);
-
- string directoryPrefix;
-
- directoryPrefix = Crestron.SimplSharp.CrestronIO.Directory.GetApplicationRootDirectory();
-
- if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows OS
+ try
{
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", versionString);
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Determining Platform....");
- // Check if User/ProgramX exists
- if (Directory.Exists(directoryPrefix + dirSeparator + "User"
- + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
+ string filePathPrefix;
+
+ var dirSeparator = Global.DirectorySeparator;
+
+ var version = Crestron.SimplSharp.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
+
+ var versionString = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build);
+
+ string directoryPrefix;
+
+ directoryPrefix = Crestron.SimplSharp.CrestronIO.Directory.GetApplicationRootDirectory();
+
+ if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows OS
{
- Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber);
- filePathPrefix = directoryPrefix + dirSeparator + "User"
- + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", versionString);
+
+ // Check if User/ProgramX exists
+ if (Directory.Exists(directoryPrefix + dirSeparator + "User"
+ + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
+ {
+ Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber);
+ filePathPrefix = directoryPrefix + dirSeparator + "User"
+ + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
+ }
+ // Check if Nvram/Programx exists
+ else if (Directory.Exists(directoryPrefix + dirSeparator + "Nvram"
+ + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
+ {
+ Debug.Console(0, @"Nvram/program{0} directory found", InitialParametersClass.ApplicationNumber);
+ filePathPrefix = directoryPrefix + dirSeparator + "Nvram"
+ + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
+ }
+ // If neither exists, set path to User/ProgramX
+ else
+ {
+ Debug.Console(0, @"No previous directory found. Using User/program{0}", InitialParametersClass.ApplicationNumber);
+ filePathPrefix = directoryPrefix + dirSeparator + "User"
+ + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
+ }
}
- // Check if Nvram/Programx exists
- else if (Directory.Exists(directoryPrefix + dirSeparator + "Nvram"
- + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
+ else // Handles Linux OS (Virtual Control)
{
- Debug.Console(0, @"Nvram/program{0} directory found", InitialParametersClass.ApplicationNumber);
- filePathPrefix = directoryPrefix + dirSeparator + "Nvram"
- + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
- }
- // If neither exists, set path to User/ProgramX
- else
- {
- Debug.Console(0, @"No previous directory found. Using User/program{0}", InitialParametersClass.ApplicationNumber);
- filePathPrefix = directoryPrefix + dirSeparator + "User"
- + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on Virtual Control Server", versionString);
+
+ // Set path to User/
+ filePathPrefix = directoryPrefix + dirSeparator + "User" + dirSeparator;
}
+
+ Global.SetFilePathPrefix(filePathPrefix);
}
- else // Handles Linux OS (Virtual Control)
+ catch (Exception e)
{
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on Virtual Control Server", versionString);
-
- // Set path to User/
- filePathPrefix = directoryPrefix + dirSeparator + "User" + dirSeparator;
+ Debug.Console(0, "Unable to Determine Platform due to Exception: {0}", e.Message);
}
-
- Global.SetFilePathPrefix(filePathPrefix);
}
///
@@ -141,6 +152,8 @@ namespace PepperDash.Essentials
{
try
{
+ //Debug.SetDoNotLoadOnNextBoot(false);
+
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration");
var filesReady = SetupFilesystem();
@@ -335,7 +348,7 @@ namespace PepperDash.Essentials
{
var sysMon = DeviceManager.GetDeviceForKey("systemMonitor") as PepperDash.Essentials.Core.Monitoring.SystemMonitorController;
- var appServer = DeviceManager.GetDeviceForKey("appServer") as CotijaSystemController;
+ var appServer = DeviceManager.GetDeviceForKey("appServer") as MobileControlSystemController;
if (sysMon != null && appServer != null)
@@ -489,13 +502,13 @@ namespace PepperDash.Essentials
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Cotija Bridge...");
- // Cotija bridge
- var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom);
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
+ // Mobile Control bridge
+ var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom);
AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
DeviceManager.AddDevice(bridge);
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Cotija Bridge Added...");
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added...");
}
else if (room is EssentialsHuddleVtc1Room)
{
@@ -504,9 +517,9 @@ namespace PepperDash.Essentials
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Cotija Bridge...");
- // Cotija bridge
- var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(room);
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
+ // Mobile Control bridge
+ var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room);
AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
DeviceManager.AddDevice(bridge);
}
@@ -529,11 +542,11 @@ namespace PepperDash.Essentials
/// Helps add the post activation steps that link bridges to main controller
///
///
- void AddBridgePostActivationHelper(CotijaBridgeBase bridge)
+ void AddBridgePostActivationHelper(MobileControlBridgeBase bridge)
{
bridge.AddPostActivationAction(() =>
{
- var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as CotijaSystemController;
+ var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as MobileControlSystemController;
if (parent == null)
{
Debug.Console(0, bridge, "ERROR: Cannot connect app server room bridge. System controller not present");
diff --git a/PepperDashEssentials/Factory/DeviceFactory.cs b/PepperDashEssentials/Factory/DeviceFactory.cs
index ddee8361..24c4bfe1 100644
--- a/PepperDashEssentials/Factory/DeviceFactory.cs
+++ b/PepperDashEssentials/Factory/DeviceFactory.cs
@@ -61,18 +61,18 @@ namespace PepperDash.Essentials
else if (typeName == "appserver")
{
- var props = JsonConvert.DeserializeObject(properties.ToString());
- return new CotijaSystemController(key, name, props);
+ var props = JsonConvert.DeserializeObject(properties.ToString());
+ return new MobileControlSystemController(key, name, props);
}
else if (typeName == "mobilecontrolbridge-ddvc01")
{
var comm = CommFactory.GetControlPropertiesConfig(dc);
- var bridge = new PepperDash.Essentials.Room.Cotija.CotijaDdvc01RoomBridge(key, name, comm.IpIdInt);
+ var bridge = new PepperDash.Essentials.Room.MobileControl.MobileControlDdvc01RoomBridge(key, name, comm.IpIdInt);
bridge.AddPreActivationAction(() =>
{
- var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as CotijaSystemController;
+ var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as MobileControlSystemController;
if (parent == null)
{
Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present");
diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj
index 348a84a5..a238a4e8 100644
--- a/PepperDashEssentials/PepperDashEssentials.csproj
+++ b/PepperDashEssentials/PepperDashEssentials.csproj
@@ -184,12 +184,12 @@
-
-
+
+
-
-
-
+
+
+
@@ -238,7 +238,7 @@
-
+
diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs
index 7077d9c2..b34e923b 100644
--- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs
+++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs
@@ -38,6 +38,12 @@ namespace PepperDash.Essentials.Room.Config
{
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
}
+ else if (typeName == "dualdisplay")
+ {
+ var rm = new EssentialsDualDisplayRoom(roomConfig);
+
+ return rm;
+ }
return null;
}
diff --git a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs
index 79a5f7df..44c88724 100644
--- a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs
+++ b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs
@@ -15,7 +15,7 @@ using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
-namespace PepperDash.Essentials.Room.Types
+namespace PepperDash.Essentials
{
public class EssentialsDualDisplayRoom : EssentialsNDisplayRoomBase, IHasCurrentVolumeControls,
IRunRouteAction, IPrivacy, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasInCallFeedback
@@ -174,9 +174,11 @@ namespace PepperDash.Essentials.Room.Types
var leftDisp = PropertiesConfig.Displays[eSourceListItemDestinationTypes.leftDisplay];
if (leftDisp != null)
{
-
if (!string.IsNullOrEmpty(leftDisp.Key))
+ {
LeftDisplay = DeviceManager.GetDeviceForKey(leftDisp.Key) as IRoutingSinkWithSwitching;
+ Displays.Add(eSourceListItemDestinationTypes.leftDisplay, LeftDisplay);
+ }
else
Debug.Console(0, this, "Unable to get LeftDisplay for Room");
}
@@ -184,9 +186,11 @@ namespace PepperDash.Essentials.Room.Types
var rightDisp = PropertiesConfig.Displays[eSourceListItemDestinationTypes.rightDisplay];
if (rightDisp != null)
{
-
if (!string.IsNullOrEmpty(rightDisp.Key))
+ {
LeftDisplay = DeviceManager.GetDeviceForKey(rightDisp.Key) as IRoutingSinkWithSwitching;
+ Displays.Add(eSourceListItemDestinationTypes.rightDisplay, RightDisplay);
+ }
else
Debug.Console(0, this, "Unable to get LeftDisplay for Room");
}
diff --git a/PepperDashEssentials/Room/Types/EssentialsNDisplayRoomBase.cs b/PepperDashEssentials/Room/Types/EssentialsNDisplayRoomBase.cs
index 677c4048..85f52c9f 100644
--- a/PepperDashEssentials/Room/Types/EssentialsNDisplayRoomBase.cs
+++ b/PepperDashEssentials/Room/Types/EssentialsNDisplayRoomBase.cs
@@ -12,21 +12,21 @@ using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.Config;
-namespace PepperDash.Essentials.Room.Types
+namespace PepperDash.Essentials
{
///
/// Base class for rooms with more than a single display
///
- public abstract class EssentialsNDisplayRoomBase : EssentialsRoomBase
+ public abstract class EssentialsNDisplayRoomBase : EssentialsRoomBase, IHasMultipleDisplays
{
//public event SourceInfoChangeHandler CurrentSingleSourceChange;
+ public Dictionary Displays { get; protected set;}
public EssentialsNDisplayRoomBase(DeviceConfig config)
: base (config)
{
-
- var propertiesConfig = JsonConvert.DeserializeObject(config.Properties.ToString());
+ Displays = new Dictionary();
}
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/EssentialsConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/EssentialsConfig.cs
index 69f162d0..cc3375e2 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/EssentialsConfig.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/EssentialsConfig.cs
@@ -21,8 +21,6 @@ namespace PepperDash.Essentials.Core.Config
public string TemplateUrl { get; set; }
- //public CotijaConfig Cotija { get; private set; }
-
[JsonProperty("systemUuid")]
public string SystemUuid
{
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs
index 745f161d..36f390c3 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs
@@ -22,6 +22,14 @@ namespace PepperDash.Essentials.Core
IRoutingSinkWithSwitching DefaultDisplay { get; }
}
+ ///
+ /// For rooms with multiple displays
+ ///
+ public interface IHasMultipleDisplays
+ {
+ Dictionary Displays { get; }
+ }
+
///
/// For rooms with routing
///
@@ -30,8 +38,6 @@ namespace PepperDash.Essentials.Core
void RunRouteAction(string routeKey);
void RunRouteAction(string routeKey, Action successCallback);
-
-
}
///
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs
index 118bdc0a..0c642d5c 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs
@@ -31,7 +31,6 @@ namespace PepperDash.Essentials.Core
event SourceInfoChangeHandler CurrentSourceChange;
}
-
///
/// Defines a class that has a collection of RoutingInputPorts
///
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs
index a6a16e08..fe7a0015 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs
@@ -32,10 +32,10 @@ namespace PepperDash.Essentials.Core
public enum eRoutingSignalType
{
Audio = 1,
- Video = 2,
- //AudioVideo = 4,
- UsbOutput = 4,
- UsbInput = 8
+ Video = 2,
+ AudioVideo = 4,
+ UsbOutput = 8,
+ UsbInput = 16
}
public enum eRoutingPortConnectionType
diff --git a/essentials-framework/pepperdashcore-builds b/essentials-framework/pepperdashcore-builds
index 07f4c597..45949f09 160000
--- a/essentials-framework/pepperdashcore-builds
+++ b/essentials-framework/pepperdashcore-builds
@@ -1 +1 @@
-Subproject commit 07f4c5975f72eeccc650cda24872d74364f6be35
+Subproject commit 45949f09bdcf6548be7fdf5c860ea4e3a5cf152d