diff --git a/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs b/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs
index ea217f28..54261370 100644
--- a/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs
+++ b/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs
@@ -1,89 +1,89 @@
-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,
+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);
- CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
+ CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
}
///
@@ -100,614 +100,613 @@ namespace PepperDash.Essentials
}));
}
- }
-
- ///
- /// 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);
- }
-
- }
-
- ///
- /// 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)
+ }
+
+ ///
+ /// 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);
+
+ 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);
+ }
+
+ }
+
+ ///
+ /// 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)
{
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)
- {
- 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");
- }
- }
+ }));
+
+ 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
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IChannelExtensions.cs b/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IChannelExtensions.cs
index b26a7f99..dd23d85a 100644
--- a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IChannelExtensions.cs
+++ b/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IChannelExtensions.cs
@@ -14,9 +14,9 @@ namespace PepperDash.Essentials.Room.Cotija
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
- controller.AddAction(prefix + "chanup", new PressAndHoldAction(dev.ChannelUp));
- controller.AddAction(prefix + "chandown", new PressAndHoldAction(dev.ChannelDown));
- controller.AddAction(prefix + "lastchan", new PressAndHoldAction(dev.LastChannel));
+ controller.AddAction(prefix + "chanUp", new PressAndHoldAction(dev.ChannelUp));
+ controller.AddAction(prefix + "chanDown", new PressAndHoldAction(dev.ChannelDown));
+ controller.AddAction(prefix + "lastChan", new PressAndHoldAction(dev.LastChannel));
controller.AddAction(prefix + "guide", new PressAndHoldAction(dev.Guide));
controller.AddAction(prefix + "info", new PressAndHoldAction(dev.Info));
controller.AddAction(prefix + "exit", new PressAndHoldAction(dev.Exit));
@@ -26,9 +26,9 @@ namespace PepperDash.Essentials.Room.Cotija
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
- controller.RemoveAction(prefix + "chanup");
- controller.RemoveAction(prefix + "chandown");
- controller.RemoveAction(prefix + "lastchan");
+ controller.RemoveAction(prefix + "chanUp");
+ controller.RemoveAction(prefix + "chanDown");
+ controller.RemoveAction(prefix + "lastChan");
controller.RemoveAction(prefix + "guide");
controller.RemoveAction(prefix + "info");
controller.RemoveAction(prefix + "exit");
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/INumericExtensions.cs b/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/INumericExtensions.cs
index 7246cb51..4f35e238 100644
--- a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/INumericExtensions.cs
+++ b/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/INumericExtensions.cs
@@ -24,8 +24,8 @@ namespace PepperDash.Essentials.Room.Cotija
controller.AddAction(prefix + "num7", new PressAndHoldAction(dev.Digit0));
controller.AddAction(prefix + "num8", new PressAndHoldAction(dev.Digit0));
controller.AddAction(prefix + "num9", new PressAndHoldAction(dev.Digit0));
- controller.AddAction(prefix + "dash", new PressAndHoldAction(dev.KeypadAccessoryButton1));
- controller.AddAction(prefix + "enter", new PressAndHoldAction(dev.KeypadAccessoryButton2));
+ controller.AddAction(prefix + "numDash", new PressAndHoldAction(dev.KeypadAccessoryButton1));
+ controller.AddAction(prefix + "numEnter", new PressAndHoldAction(dev.KeypadAccessoryButton2));
// Deal with the Accessory functions on the numpad later
}
@@ -42,9 +42,9 @@ namespace PepperDash.Essentials.Room.Cotija
controller.RemoveAction(prefix + "num6");
controller.RemoveAction(prefix + "num7");
controller.RemoveAction(prefix + "num8");
- controller.RemoveAction(prefix + "num9");
- controller.RemoveAction(prefix + "dash");
- controller.RemoveAction(prefix + "enter");
+ controller.RemoveAction(prefix + "num9");
+ controller.RemoveAction(prefix + "numDash");
+ controller.RemoveAction(prefix + "numEnter");
}
}
}
\ No newline at end of file
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IPowerExtensions.cs b/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IPowerExtensions.cs
index 68b36675..732d2740 100644
--- a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IPowerExtensions.cs
+++ b/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/IPowerExtensions.cs
@@ -14,18 +14,18 @@ namespace PepperDash.Essentials.Room.Cotija
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
- controller.AddAction(prefix + "poweron", new Action(dev.PowerOn));
- controller.AddAction(prefix + "poweroff", new Action(dev.PowerOff));
- controller.AddAction(prefix + "powertoggle", new Action(dev.PowerToggle));
+ controller.AddAction(prefix + "powerOn", new Action(dev.PowerOn));
+ controller.AddAction(prefix + "powerOff", new Action(dev.PowerOff));
+ controller.AddAction(prefix + "powerToggle", new Action(dev.PowerToggle));
}
public static void UnlinkActions(this IPower dev, CotijaSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
- controller.RemoveAction(prefix + "poweron");
- controller.RemoveAction(prefix + "poweroff");
- controller.RemoveAction(prefix + "powertoggle");
+ controller.RemoveAction(prefix + "powerOn");
+ controller.RemoveAction(prefix + "powerOff");
+ controller.RemoveAction(prefix + "powerToggle");
}
}
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs b/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs
index 7fa7d1b1..99198fa6 100644
--- a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs
+++ b/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ISetTopBoxControlsExtensions.cs
@@ -14,7 +14,7 @@ namespace PepperDash.Essentials.Room.Cotija
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
- controller.AddAction(prefix + "dvrlist", new PressAndHoldAction(dev.DvrList));
+ controller.AddAction(prefix + "dvrList", new PressAndHoldAction(dev.DvrList));
controller.AddAction(prefix + "replay", new PressAndHoldAction(dev.Replay));
}
@@ -22,7 +22,7 @@ namespace PepperDash.Essentials.Room.Cotija
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
- controller.RemoveAction(prefix + "dvrlist");
+ controller.RemoveAction(prefix + "dvrList");
controller.RemoveAction(prefix + "replay");
}
}
diff --git a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ITransportExtensions.cs b/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ITransportExtensions.cs
index 34bda457..9463d95f 100644
--- a/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ITransportExtensions.cs
+++ b/PepperDashEssentials/Room/Cotija/DeviceTypeInterfaces/ITransportExtensions.cs
@@ -17,8 +17,8 @@ namespace PepperDash.Essentials.Room.Cotija
controller.AddAction(prefix + "play", new PressAndHoldAction(dev.Play));
controller.AddAction(prefix + "pause", new PressAndHoldAction(dev.Pause));
controller.AddAction(prefix + "stop", new PressAndHoldAction(dev.Stop));
- controller.AddAction(prefix + "prevtrack", new PressAndHoldAction(dev.ChapPlus));
- controller.AddAction(prefix + "nexttrack", new PressAndHoldAction(dev.ChapMinus));
+ controller.AddAction(prefix + "prevTrack", new PressAndHoldAction(dev.ChapPlus));
+ controller.AddAction(prefix + "nextTrack", new PressAndHoldAction(dev.ChapMinus));
controller.AddAction(prefix + "rewind", new PressAndHoldAction(dev.Rewind));
controller.AddAction(prefix + "ffwd", new PressAndHoldAction(dev.FFwd));
controller.AddAction(prefix + "record", new PressAndHoldAction(dev.Record));
@@ -31,8 +31,8 @@ namespace PepperDash.Essentials.Room.Cotija
controller.RemoveAction(prefix + "play");
controller.RemoveAction(prefix + "pause");
controller.RemoveAction(prefix + "stop");
- controller.RemoveAction(prefix + "prevtrack");
- controller.RemoveAction(prefix + "nexttrack");
+ controller.RemoveAction(prefix + "prevTrack");
+ controller.RemoveAction(prefix + "nextTrack");
controller.RemoveAction(prefix + "rewind");
controller.RemoveAction(prefix + "ffwd");
controller.RemoveAction(prefix + "record");
diff --git a/PepperDashEssentials/Room/Cotija/RoomBridges/CotijaDdvc01RoomBridge.cs b/PepperDashEssentials/Room/Cotija/RoomBridges/CotijaDdvc01RoomBridge.cs
index 78512263..362777c3 100644
--- a/PepperDashEssentials/Room/Cotija/RoomBridges/CotijaDdvc01RoomBridge.cs
+++ b/PepperDashEssentials/Room/Cotija/RoomBridges/CotijaDdvc01RoomBridge.cs
@@ -1,336 +1,342 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-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);
- }));
-
-#warning CHANGE to activityshare. Perhaps
- Parent.AddAction(@"/room/room1/defaultsource", new Action(() =>
- EISC.PulseBool(BoolJoin.ActivitySharePress)));
-
- Parent.AddAction(@"/room/room1/masterVolumeLevel", new Action(u =>
- EISC.SetUshort(UshortJoin.MasterVolumeLevel, u)));
- Parent.AddAction(@"/room/room1/masterVolumeMuteToggle", 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();
-
+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);
+ }));
+
+#warning CHANGE to activityshare. Perhaps
+ Parent.AddAction(@"/room/room1/defaultsource", new Action(() =>
+ EISC.PulseBool(BoolJoin.ActivitySharePress)));
+
+ Parent.AddAction(@"/room/room1/masterVolumeLevel", new Action(u =>
+ EISC.SetUshort(UshortJoin.MasterVolumeLevel, u)));
+ Parent.AddAction(@"/room/room1/masterVolumeMuteToggle", 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(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
- {
- masterVolumeLevel = u
- }));
-
- EISC.SetBoolSigAction(BoolJoin.MasterVolumeIsMuted, b =>
- PostStatusMessage(new
- {
- masterVolumeMuteState = 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;
-
- //Room
- if (co.Rooms == null)
- co.Rooms = new List();
+ }
+ }
+
+ ///
+ /// 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
+ {
+ masterVolumeLevel = u
+ }));
+
+ EISC.SetBoolSigAction(BoolJoin.MasterVolumeIsMuted, b =>
+ PostStatusMessage(new
+ {
+ masterVolumeMuteState = 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)
{
@@ -341,284 +347,284 @@ namespace PepperDash.Essentials.Room.Cotija
{
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)
- {
- PostStatusMessage(new
- {
- isOn = EISC.BooleanOutput[BoolJoin.RoomIsOn].BoolValue,
- selectedSourceKey = EISC.StringOutput[StringJoin.SelectedSourceKey].StringValue,
- masterVolumeLevel = EISC.UShortOutput[UshortJoin.MasterVolumeLevel].UShortValue,
- masterVolumeMuteState = EISC.BooleanOutput[BoolJoin.MasterVolumeIsMuted].BoolValue
- });
- }
- 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);
- // }
- //}
- }
- }
+ }
+ 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)
+ {
+ PostStatusMessage(new
+ {
+ isOn = EISC.BooleanOutput[BoolJoin.RoomIsOn].BoolValue,
+ selectedSourceKey = EISC.StringOutput[StringJoin.SelectedSourceKey].StringValue,
+ masterVolumeLevel = EISC.UShortOutput[UshortJoin.MasterVolumeLevel].UShortValue,
+ masterVolumeMuteState = EISC.BooleanOutput[BoolJoin.MasterVolumeIsMuted].BoolValue
+ });
+ }
+ 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/SourceDeviceMapDictionary.cs b/PepperDashEssentials/Room/Cotija/RoomBridges/SourceDeviceMapDictionary.cs
index ecd29d59..06d64f94 100644
--- a/PepperDashEssentials/Room/Cotija/RoomBridges/SourceDeviceMapDictionary.cs
+++ b/PepperDashEssentials/Room/Cotija/RoomBridges/SourceDeviceMapDictionary.cs
@@ -42,23 +42,23 @@ namespace PepperDash.Essentials.Room.Cotija
{"preset23", 123},
{"preset24", 124},
- {"key0", 130},
- {"key1", 131},
- {"key2", 132},
- {"key3", 133},
- {"key4", 134},
- {"key5", 135},
- {"key6", 136},
- {"key7", 137},
- {"key8", 138},
- {"key9", 139},
- {"keyDash", 140},
- {"keyEnter", 141},
- {"channelUp", 142},
- {"channelDown", 143},
- {"channelLast", 144},
+ {"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},
- {"power", 146},
+ {"powerToggle", 146},
{"red", 147},
{"green", 148},
{"yellow", 149},
@@ -71,21 +71,27 @@ namespace PepperDash.Essentials.Room.Cotija
{"closedCaption", 156},
{"stop", 157},
{"pause", 158},
- {"cursorUp", 159},
- {"cursorDown", 160},
- {"cursorLeft", 161},
- {"cursorRight", 162},
+ {"up", 159},
+ {"down", 160},
+ {"left", 161},
+ {"right", 162},
{"settings", 163},
{"info", 164},
{"return", 165},
{"guide", 166},
{"reboot", 167},
-
+ {"dvrList", 168},
+ {"replay", 169},
{"play", 170},
- {"cursorOk", 171},
+ {"select", 171},
{"record", 172},
{"menu", 173},
- {"topMenu", 174}
+ {"topMenu", 174},
+ {"prevTrack", 175},
+ {"nextTrack", 176},
+ {"powerOn", 177},
+ {"powerOff", 178}
+
};
diff --git a/Release Package/PepperDashEssentials.cpz b/Release Package/PepperDashEssentials.cpz
index 102c997c..f0921bce 100644
Binary files a/Release Package/PepperDashEssentials.cpz and b/Release Package/PepperDashEssentials.cpz differ
diff --git a/Release Package/PepperDashEssentials.dll b/Release Package/PepperDashEssentials.dll
index 7bb8d442..5a40fd8f 100644
Binary files a/Release Package/PepperDashEssentials.dll and b/Release Package/PepperDashEssentials.dll differ