Compare commits

...

127 Commits

Author SHA1 Message Date
Neil Dorin
e7253b4acc Merged in bugfix/ecs-1062 (pull request #8)
Bugfix/ecs 1062

Approved-by: Neil Dorin <ndorin@pepperdash.com>
2019-04-02 22:19:37 +00:00
Neil Dorin
71a27027e7 Updates framework commit to development branch 2019-04-02 16:04:46 -06:00
Neil Dorin
2655b8f7b8 Resolves issue with HuddleVtc1Room adding Emergency device in CustomActivate() which would throw an exception in DeviceManager.ActivateAll() when attempting to iterate the modified devices dictionary 2019-04-02 15:58:12 -06:00
Neil Dorin
3adee8bc30 Resolves ecs-1042 2019-03-18 11:25:46 -06:00
Neil Dorin
e3a3a2cd2d Attempting to resolve exception in CotijaSystemController when SystemMonitor tries to notify AppServer of program start before WSClient is *really* connected. 2019-03-15 14:42:47 -06:00
Neil Dorin
6235b44d89 Updates to delete any existing archived configs during update process to prevent name conflicts 2019-03-15 12:16:01 -06:00
Neil Dorin
90bbd65fdc Add lastest essentials framework 2019-03-14 10:41:07 -06:00
Neil Dorin
43fd263ea1 Config Update Working 2019-03-13 16:33:51 -06:00
Neil Dorin
038e23289e Adds inital ConfigMessenger 2019-03-12 11:08:32 -06:00
Neil Dorin
2121456d50 Adds fake directory to MockVC with full features 2019-03-08 16:56:37 -07:00
Neil Dorin
3a99c3bb30 Adds PrefixDictionaryFolderItems method to add "[+] " prefix to folder names for MC. 2019-03-07 16:31:56 -07:00
Neil Dorin
52ac57c080 fixed vc directory browsing to properly sync between MC and Essentials UIs 2019-03-07 15:20:24 -07:00
Neil Dorin
84ee743ff5 Moved Directory browsing logic from VideoCodecUiDriver down to IHasDirectory Interface to sync better with VideoCodecBaseMessenger for MC 2019-03-06 16:33:00 -07:00
Neil Dorin
24fb74701a Working on moving codec browsing data from UI into codec class 2019-03-05 16:31:13 -07:00
Neil Dorin
1c9aa1eaf6 Moves setting program initialization value out of InitializeSystem() to SystemMonitorController class 2019-03-05 11:33:39 -07:00
Heath Volmer
7c88843f50 Changed one directory message path for mobile control 2019-03-05 10:08:04 -07:00
Heath Volmer
7a3ce5fcf1 Added interface to huddle room to enable volume controls 2019-03-04 11:56:55 -07:00
Neil Dorin
3049e5a041 Merge branch 'feature/ecs-963' into HEAD 2019-02-27 14:27:44 -07:00
Heath Volmer
59234274dc Source-none confirmed; camera selects and FB 2019-02-25 17:51:17 -07:00
Heath Volmer
120dae2e63 Changed SourceNone to Source-None 2019-02-25 12:08:35 -07:00
Heath Volmer
e4317825d3 Create 'none' source 2019-01-30 17:23:57 -07:00
Neil Dorin
bf6971a52d Adds ability to have configuration filenames with prefixes or suffixes. 2019-01-29 17:50:46 -07:00
Heath Volmer
ef0a8dd3b9 Don't know, screw this 2019-01-29 15:09:45 -07:00
Heath Volmer
ca42d744cf Directory browsing largely alive for Weil 2019-01-29 09:33:01 -07:00
Neil Dorin
ffa4de49e9 Changes default folder to user/programX. Will fail back to nvram/programX if found, otherwise if no default folder found, will create user/programX. 2019-01-28 16:18:06 -07:00
Heath Volmer
3c5c157a70 Framework-sub changes 2019-01-28 11:09:43 -07:00
Heath Volmer
8ef58359e7 Added directory browsing things for DDVC01 2019-01-26 15:54:24 -07:00
Heath Volmer
530e1ebcb8 Smash system monitor bug 2019-01-24 11:20:24 -07:00
Heath Volmer
8d03bef34f Added missing join constants in Ddvc01RoomBridge 2019-01-24 09:20:29 -07:00
Heath Volmer
a870418f96 Added Ddvc01VtcMessenger; added to bridge; basic functions and feedbacks 2019-01-22 12:00:50 -07:00
Jason Alborough
37e2dfd11f Merged in JTA and about 1000 other things! (pull request #5)
JTA
2019-01-21 18:20:55 +00:00
Jason T Alborough
6c02423a1c Adds DisplayControllerBRidge 2019-01-21 11:42:47 -05:00
Jason T Alborough
6ea966ec6c Adds the CameraCOntroller to the BridgeFactory 2019-01-21 11:40:48 -05:00
Jason T Alborough
6e9b24576e Fixes issue in the DmChassisControllerBRidge wher ethe Tx input sysnc was not getting properly connected. 2019-01-21 11:34:37 -05:00
Jason T Alborough
ad04235061 Adds CameraContorllerBridge 2019-01-21 10:57:11 -05:00
Jason T Alborough
34f3e543f2 Adds Display Controller base with some basic functioanlity. 2019-01-11 20:22:23 -05:00
Jason T Alborough
e145bfbaee Merge remote-tracking branch 'origin/feature/ecs-994' into JTA 2019-01-10 10:51:38 -05:00
Jason T Alborough
4f726007b8 Adds merged Essentials core 2019-01-10 10:51:18 -05:00
Jason T Alborough
d62b5b7e0c Starts DisplayControllerBridge
Starts DspControllerBridge.
Note these are not yet functional.
2019-01-10 10:49:08 -05:00
Neil Dorin
967d281b62 Includes essentials-framework commit that adds ability for a DM-RMC-4KZ-100-C to be created. 2019-01-08 14:29:53 -07:00
Jason T Alborough
be9fd5e8d1 Adds IsOnline FB to GenericLightingBridge 2019-01-03 17:27:07 -05:00
Jason T Alborough
f25d05edc2 Adds GenericLightingBridge 2019-01-02 12:52:30 -05:00
Neil Dorin
c3d6890a4c Minor updates from testing MC 2018-12-21 16:12:43 -07:00
Neil Dorin
ff6184c241 Adds AudioCodecBaseMessenger and includes updates for Audio Codec on EssentialsHuddleVtc1Room type and for use in Mobile Control 2018-12-20 17:01:34 -07:00
Neil Dorin
034c6913f7 Adds call history messages to VideoCodecBaseMessenger. Removes all call related messages from CotijaEssentialsHuddleSpaceRoomBridge 2018-12-19 16:03:08 -07:00
Joshua Gutenplan
03da699a36 pull essentials updates into vance sub mod 2018-12-18 19:07:44 -08:00
Neil Dorin
3a3f6db692 Updates to fix issues with sending individual program status messages to the app server. Minor updates to AtcDdvc01Messenger based on testing MC with Heath 2018-12-18 17:22:33 -07:00
Neil Dorin
87a449d1ee Silenced AppServer heartbeat console messages. Added isInCall property to Atc status message in AtcDdvc01Messenger SendFullStatus() 2018-12-17 16:28:19 -07:00
Jason T Alborough
1d6a835323 CHanges submodule to merged commit 2018-12-17 11:12:33 -05:00
Jason T Alborough
6bbad2e0f9 Merge remote-tracking branch 'origin/feature/ecs-967' into JTA
# Conflicts:
#	PepperDashEssentials/AppServer/CotijaSystemController.cs
#	PepperDashEssentials/Bridges/BridgeBase.cs
#	PepperDashEssentials/Bridges/IBasicCommunicationBridge.cs
#	PepperDashEssentials/PepperDashEssentials.csproj
#	Release Package/PepperDashEssentials.cpz
#	Release Package/PepperDashEssentials.dll
#	essentials-framework
2018-12-17 11:11:14 -05:00
Neil Dorin
821f2a6d60 Updates from testing System Monitor messaging with AppServer 2018-12-14 16:56:17 -07:00
Neil Dorin
f6136a8c77 Adds SystemMonitroMessenger to bridge between SystemMonitorController and AppServer (untested) 2018-12-12 16:23:17 -07:00
Neil Dorin
676526ed48 Merge remote-tracking branch 'origin/bugfix/mob-470' into feature/ecs-967
# Conflicts:
#	PepperDashEssentials/AppServer/CotijaSystemController.cs
#	PepperDashEssentials/AppServer/RoomBridges/CotijaDdvc01RoomBridge.cs
#	PepperDashEssentials/ControlSystem.cs
#	PepperDashEssentials/OTHER/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs
#	PepperDashEssentials/OTHER/Fusion/EssentialsHuddleVtc1FusionController.cs
#	PepperDashEssentials/Properties/AssemblyInfo.cs
#	PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs
#	devjson commands.json
2018-12-12 13:34:32 -07:00
Neil Dorin
a8ffe2d09f Adds merged essentials-framework branch 2018-12-12 13:13:34 -07:00
Neil Dorin
541fbbbb2d Testing SytemMonitorBridge 2018-12-12 12:59:00 -07:00
Neil Dorin
3a5686c27a Testing SystemMonitorBridge 2018-12-11 17:58:52 -07:00
Neil Dorin
531e7186f2 Added feedback/action linking to SystemMonitorBridge 2018-12-10 16:33:24 -07:00
Neil Dorin
9bc0269e78 Updates to SystemMonitorBridge 2018-12-07 17:30:51 -07:00
Neil Dorin
0df53facb1 Starting on SystemMonitorBridge 2018-12-06 17:24:55 -07:00
Neil Dorin
2ee77f1bca Adds System Monitor program initialization feedback to startup procedure. Adds bridges for GenericRelayDevice and IDigitalInput device tyeps. 2018-12-06 14:43:38 -07:00
Jason T Alborough
9a56f5bb49 Adds control for DigitalLogger PDU Device
Adds EiscBridge for DigitalLogger PDU Device.
2018-12-03 22:47:49 -05:00
Jason T Alborough
895f49b888 Adds some DigitalLogger funcitonality and begins merge process with new Bridge concepts. 2018-12-03 12:42:17 -05:00
Neil Dorin
e51e1930d9 Minor updates to essentials-framework 2018-11-26 12:37:47 -07:00
Neil Dorin
d245f36cf3 adds framework commit 2018-11-26 11:59:28 -07:00
Neil Dorin
a7c920b780 Added Hdcp actions and feedbacks 2018-10-08 16:55:35 -06:00
Neil Dorin
3a91a895e6 Removed Cue from Feedback 2018-10-08 15:49:21 -06:00
Heath Volmer
397b0b4d9c DDVC01 bridge, repaired device controls 2018-10-08 15:17:02 -06:00
Neil Dorin
b793c04ad3 Merge branch 'bugfix/ecs-895' into feature/ecs-877
# Conflicts:
#	PepperDashEssentials/Properties/AssemblyInfo.cs
#	PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs
#	Release Package/PepperDashEssentials.cpz
#	Release Package/PepperDashEssentials.dll
2018-10-08 13:30:18 -06:00
Neil Dorin
3d9070dc4f Updates to get Tx Hdcp support working 2018-10-05 17:20:07 -06:00
Neil Dorin
3f82eaeb66 Adds CEC support for all DM TX/RX and input/output cards 2018-10-04 17:00:44 -06:00
Heath Volmer
3cbf784417 Added messaging for code prompt login methods 2018-10-03 18:17:12 -06:00
Neil Dorin
3d6ce7534f Adds Edid and video resolution support for Dm Rmc over EiscApi bridge. Beginnings of Cec control 2018-10-03 17:49:08 -06:00
Heath Volmer
28d694d0b4 Reset of connected simpl program will no longer add duplicate audioCodec and videoCodec devices to output config 2018-10-02 13:02:46 -06:00
Neil Dorin
a320eff13c Updated join map to fix issue with audio/video source selection and feedback 2018-10-01 19:34:53 -06:00
Neil Dorin
f7db0ef36c Working on implementing video and audio source control/feedback for TXs 2018-09-28 17:08:21 -06:00
Heath Volmer
184144dc3c Touchups to ddvc mob codec messages 2018-09-27 17:50:04 -06:00
Neil Dorin
dfd7cb4411 Adds DmTxControllerBridge 2018-09-27 17:27:35 -06:00
Heath Volmer
5014343fa3 DDVC01 - MOB ATC messaging changes 2018-09-27 10:50:23 -06:00
Neil Dorin
f2bfeda074 Tested DmChassisController over EiscApi bridge. So far, no issues found 2018-09-26 16:09:43 -06:00
Neil Dorin
339a4f8a62 Adds DmChassicControllerBridge. Created JoinMapBase base class 2018-09-25 17:19:53 -06:00
Heath Volmer
78668e8abb Added config construction for audio conf in DDVC MOB bridge 2018-09-25 14:36:38 -06:00
Heath Volmer
101d1b5625 Added handler for phone call activity, DDVC bridge 2018-09-24 15:01:02 -06:00
Neil Dorin
780f7bc249 Added joinmap for IBasicCommunication and testet Com, Tcp, Ssh 2018-09-24 10:39:55 -06:00
Neil Dorin
6ec0295aba Progress on comm bridge 2018-09-20 17:13:54 -06:00
Neil Dorin
d98b7e837a Commit before switching branches 2018-09-20 14:14:59 -06:00
Heath Volmer
99da6debdc Switched Websocket to synchronous Send method. Seems to prevent data loss 2018-09-19 11:46:52 -06:00
Neil Dorin
c2665f0225 Added first set of interface extension methods for linking devices to EISC sigs 2018-09-18 17:54:45 -06:00
Neil Dorin
0406361d75 Updates from testing UI reconnecting to room after room properties update from Fusion 2018-09-18 17:53:33 -06:00
Neil Dorin
182326b3c5 Updated EssentialsRoomBase and both extented types to use ReconfigurableDevice. Tested Fusion Custom Properties successfully updating room name and help message. 2018-09-14 21:26:25 -06:00
Jason T Alborough
4a69207038 ECS-838 Add method to set lighting integrationID from Bridge. 2018-09-14 16:55:22 -04:00
Jason T Alborough
7b4aad3516 Modifications to EssentialsDsp Bridge
As installed in Wharton HH.8th floor 2018-09-14
2018-09-14 09:12:47 -04:00
Neil Dorin
8dabe732ec Renamed Config in Essentials room type classes to PropertiesConfig and modified EssentialsRoomBase to derive from ReconfigurableDevice 2018-09-13 16:50:08 -06:00
Jason T Alborough
410cf1b4ad ECS-839 Add autoAnswer Support to QscDialer and Bridge
ECS-836 Add DigitalLogger PowerController to Devices with Temp Bridge. This is just stared. Not yet complete
2018-09-12 18:54:33 -04:00
Heath Volmer
ee6293fa75 Added MessengerBase class to app server stuff 2018-09-12 13:53:35 -06:00
Heath Volmer
873fd81b5c Added debug command to log marker in log 2018-09-11 10:04:41 -06:00
Heath Volmer
a2a3f4caed Clean up extra verbose logging after solidifying reconnection 2018-09-11 08:13:14 -06:00
Heath Volmer
1df658b7eb Added close handlers to catch legit shutdowns from servers 2018-09-10 20:23:57 -06:00
Heath Volmer
1c9061cc28 Strengthened reconnect behavior with both app server and IIS outages 2018-09-10 13:49:56 -06:00
Heath Volmer
a0a83a1af7 Removed HTTP join procedure; rehashed reconnects 2018-09-10 13:00:03 -06:00
Heath Volmer
f17b62844d Attempting to prevent deadlock/multiple connection attempts on reconnect 2018-09-10 07:48:14 -06:00
Heath Volmer
5f8170fb66 Commit of framework 2018-09-07 18:15:39 -06:00
Heath Volmer
42086f650d Weil-related changes; app server, many websocket and http client related changes to imrpove connection resilience; Added newer pd.core 1.0.9 2018-09-07 18:09:59 -06:00
Jason T Alborough
a84084b273 Adds Online to EssentialsDsp 2018-09-06 20:08:00 -04:00
Heath Volmer
5ed8ff6dac Fixed scope issue joining sources to EISC 2018-09-04 15:39:58 -06:00
Heath Volmer
b295f931a3 ? 2018-09-04 14:31:29 -06:00
Jason T Alborough
bff8529c9f Changes to QscDialer 2018-09-03 15:33:13 -04:00
Jason T Alborough
f819d0d743 QscAtc Work form live test at Wharton HH.830. Needs more vetting. 2018-08-29 17:32:23 -04:00
Jason T Alborough
1534433949 Ecs-823 Implement Essentials Light Bridge
WHAR-1441 Add Lutron Temp Bridge
WHAR-1401 Finish testing Lighting Controls
2018-08-27 17:24:53 -04:00
Jason T Alborough
daf44ae797 Started the EssentialsLightBridge class 2018-08-25 07:28:40 -04:00
Jason T Alborough
759635b364 WHAR-1436 - Add Vol control up/down buttons on the user page 2018-08-24 14:12:53 -04:00
Jason T Alborough
96e60f6eaf Adds Hdcp Support for Tx30X and Tx201 2018-08-15 18:38:21 -04:00
Jason T Alborough
a13428fb4e Commented out a read-only property. Merge Issue mabey 2018-08-14 09:45:41 -04:00
Jason T Alborough
818d6c9ca5 Adds HdcpSupport for Tx to EssentialsDM Bridge 2018-08-14 09:44:50 -04:00
Jason T Alborough
a6df8f908b Merge branch 'development' into JTAChanges
# Conflicts:
#	essentials-framework
2018-08-13 14:51:55 -04:00
Jason T Alborough
0d5c93bbde WHAR-1397 Removes extraneous debug traces 2018-08-13 13:51:23 -04:00
Jason T Alborough
40dcca0e8d Minor changes for HDCP support. Not yet complete. 2018-08-10 18:56:09 -04:00
Jason T Alborough
ef443bdfb0 Created a device for TVOneCorio with online status and preset recall/FB
Created a temp bridge for EiscApi
2018-08-10 12:29:15 -04:00
Jason T Alborough
a900a08095 Merge branch 'Feature/QSC' of https://bitbucket.org/Pepperdash_Products/essentials into Feature/QSC 2018-08-06 11:29:06 -04:00
Jason T Alborough
fa94b83d63 Changes from Staging HH.8 2018-08-06 11:28:00 -04:00
Alex Johnson
5f119690c2 Commit for essentials-framework submodule update 2018-08-03 10:23:52 -04:00
Alex Johnson
43071a4d91 Recommit 2018-07-31 17:20:03 -04:00
Alex Johnson
4d4d50bc92 Update to framework submodule for Tx and Rx dictionary creation 2018-07-31 17:17:14 -04:00
Jason T Alborough
2e566b41a0 Removed release cpz for script compatibility. 2018-07-18 16:07:45 -04:00
Jason T Alborough
be5b23e9d1 Qsc and EssentialsDspBridge with Functional vol, mute, and preset control...still needs more work though 2018-07-18 12:13:35 -04:00
Jason T Alborough
448b408f94 Merges Essentials bridges proof of concept work into new BB.org repo 2018-07-17 08:05:02 -04:00
Jason T Alborough
e1422d8653 Changes essentials-framework branch to essentialsBridges 2018-07-17 07:12:49 -04:00
Jason T Alborough
b353b93458 Adds essentials-framework commit 2018-07-16 19:50:34 -04:00
60 changed files with 10322 additions and 7108 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Provides a messaging bridge for an AudioCodecBase device
/// </summary>
public class AudioCodecBaseMessenger : MessengerBase
{
/// <summary>
/// Device being bridged
/// </summary>
public AudioCodecBase Codec { get; set; }
/// <summary>
/// Constuctor
/// </summary>
/// <param name="key"></param>
/// <param name="codec"></param>
/// <param name="messagePath"></param>
public AudioCodecBaseMessenger(string key, AudioCodecBase codec, string messagePath)
: base(key, messagePath)
{
if (codec == null)
throw new ArgumentNullException("codec");
Codec = codec;
codec.CallStatusChange += new EventHandler<CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
}
protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
{
appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendAtcFullMessageObject));
appServerController.AddAction(MessagePath + "/dial", new Action<string>(s => Codec.Dial(s)));
appServerController.AddAction(MessagePath + "/endCallById", new Action<string>(s =>
{
var call = GetCallWithId(s);
if (call != null)
Codec.EndCall(call);
}));
appServerController.AddAction(MessagePath + "/endAllCalls", new Action(Codec.EndAllCalls));
appServerController.AddAction(MessagePath + "/dtmf", new Action<string>(s => Codec.SendDtmf(s)));
appServerController.AddAction(MessagePath + "/rejectById", new Action<string>(s =>
{
var call = GetCallWithId(s);
if (call != null)
Codec.RejectCall(call);
}));
appServerController.AddAction(MessagePath + "/acceptById", new Action<string>(s =>
{
var call = GetCallWithId(s);
if (call != null)
Codec.AcceptCall(call);
}));
}
/// <summary>
/// Helper to grab a call with string ID
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
CodecActiveCallItem GetCallWithId(string id)
{
return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
}
void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
{
SendAtcFullMessageObject();
}
/// <summary>
/// Helper method to build call status for vtc
/// </summary>
/// <returns></returns>
void SendAtcFullMessageObject()
{
var info = Codec.CodecInfo;
PostStatusMessage(new
{
isInCall = Codec.IsInCall,
calls = Codec.ActiveCalls,
info = new
{
phoneNumber = info.PhoneNumber
}
});
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Handles interactions with the app server to update the config
/// </summary>
public class ConfigMessenger : MessengerBase
{
public ConfigMessenger(string key, string messagePath)
: base(key, messagePath)
{
ConfigUpdater.ConfigStatusChanged -= ConfigUpdater_ConfigStatusChanged;
ConfigUpdater.ConfigStatusChanged += new EventHandler<ConfigStatusEventArgs>(ConfigUpdater_ConfigStatusChanged);
}
void ConfigUpdater_ConfigStatusChanged(object sender, ConfigStatusEventArgs e)
{
PostUpdateStatus(e.UpdateStatus.ToString());
}
protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
{
appServerController.AddAction(MessagePath + "/updateConfig", new Action<string>(s => GetConfigFile(s)));
}
/// <summary>
/// Generates or passes the URL to make the request to GET the config from a server
/// </summary>
/// <param name="url"></param>
void GetConfigFile(string url)
{
try
{
// Attempt to parse the URL
var parser = new Crestron.SimplSharp.Net.Http.UrlParser(url);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully parsed URL from AppServer message: {0}", parser.Url);
}
catch (Exception e)
{
// If unable to parse the URL, generate it from config data
Debug.Console(2, "Error parsing URL: {0}", e);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to parse URL from AppServer message. Generating URL from config data");
url = string.Format("http://{0}/api/system/{1}/config", AppServerController.Config.ServerUrl, AppServerController.SystemUuid);
}
ConfigUpdater.GetConfigFromServer(url);
}
/// <summary>
/// Posts a message with the current status of the config update
/// </summary>
/// <param name="status"></param>
void PostUpdateStatus(string status)
{
PostStatusMessage(new
{
updateStatus = status
});
}
}
}

View File

@@ -0,0 +1,214 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class Ddvc01AtcMessenger : MessengerBase
{
BasicTriList EISC;
/// <summary>
/// 221
/// </summary>
const uint BDialHangup = 221;
/// <summary>
/// 251
/// </summary>
const uint BIncomingAnswer = 251;
/// <summary>
/// 252
/// </summary>
const uint BIncomingReject = 252;
/// <summary>
/// 241
/// </summary>
const uint BSpeedDial1 = 241;
/// <summary>
/// 242
/// </summary>
const uint BSpeedDial2 = 242;
/// <summary>
/// 243
/// </summary>
const uint BSpeedDial3 = 243;
/// <summary>
/// 244
/// </summary>
const uint BSpeedDial4 = 244;
/// <summary>
/// 201
/// </summary>
const uint SCurrentDialString = 201;
/// <summary>
/// 211
/// </summary>
const uint SCurrentCallNumber = 211;
/// <summary>
/// 212
/// </summary>
const uint SCurrentCallName = 212;
/// <summary>
/// 221
/// </summary>
const uint SHookState = 221;
/// <summary>
/// 222
/// </summary>
const uint SCallDirection = 222;
/// <summary>
/// 201-212 0-9*#
/// </summary>
Dictionary<string, uint> DTMFMap = new Dictionary<string, uint>
{
{ "1", 201 },
{ "2", 202 },
{ "3", 203 },
{ "4", 204 },
{ "5", 205 },
{ "6", 206 },
{ "7", 207 },
{ "8", 208 },
{ "9", 209 },
{ "0", 210 },
{ "*", 211 },
{ "#", 212 },
};
/// <summary>
///
/// </summary>
CodecActiveCallItem CurrentCallItem;
/// <summary>
///
/// </summary>
/// <param name="eisc"></param>
/// <param name="messagePath"></param>
public Ddvc01AtcMessenger(string key, BasicTriList eisc, string messagePath)
: base(key, messagePath)
{
EISC = eisc;
CurrentCallItem = new CodecActiveCallItem();
CurrentCallItem.Type = eCodecCallType.Audio;
CurrentCallItem.Id = "-audio-";
}
/// <summary>
///
/// </summary>
void SendFullStatus()
{
this.PostStatusMessage(new
{
calls = GetCurrentCallList(),
currentCallString = EISC.GetString(SCurrentCallNumber),
currentDialString = EISC.GetString(SCurrentDialString),
isInCall = EISC.GetString(SHookState) == "Connected"
});
}
/// <summary>
///
/// </summary>
/// <param name="appServerController"></param>
protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
{
//EISC.SetStringSigAction(SCurrentDialString, s => PostStatusMessage(new { currentDialString = s }));
EISC.SetStringSigAction(SHookState, s =>
{
CurrentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true);
//GetCurrentCallList();
SendCallsList();
});
EISC.SetStringSigAction(SCurrentCallNumber, s =>
{
CurrentCallItem.Number = s;
SendCallsList();
});
EISC.SetStringSigAction(SCurrentCallName, s =>
{
CurrentCallItem.Name = s;
SendCallsList();
});
EISC.SetStringSigAction(SCallDirection, s =>
{
CurrentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true);
SendCallsList();
});
// Add press and holds using helper
Action<string, uint> addPHAction = (s, u) =>
AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => EISC.SetBool(u, b)));
// Add straight pulse calls
Action<string, uint> addAction = (s, u) =>
AppServerController.AddAction(MessagePath + s, new Action(() => EISC.PulseBool(u, 100)));
addAction("/endCallById", BDialHangup);
addAction("/acceptById", BIncomingAnswer);
addAction("/rejectById", BIncomingReject);
addAction("/speedDial1", BSpeedDial1);
addAction("/speedDial2", BSpeedDial2);
addAction("/speedDial3", BSpeedDial3);
addAction("/speedDial4", BSpeedDial4);
// Get status
AppServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullStatus));
// Dial on string
AppServerController.AddAction(MessagePath + "/dial", new Action<string>(s => EISC.SetString(SCurrentDialString, s)));
// Pulse DTMF
AppServerController.AddAction(MessagePath + "/dtmf", new Action<string>(s =>
{
if (DTMFMap.ContainsKey(s))
{
EISC.PulseBool(DTMFMap[s], 100);
}
}));
}
/// <summary>
///
/// </summary>
void SendCallsList()
{
PostStatusMessage(new
{
calls = GetCurrentCallList(),
});
}
/// <summary>
/// Turns the
/// </summary>
/// <returns></returns>
List<CodecActiveCallItem> GetCurrentCallList()
{
if (CurrentCallItem.Status == eCodecCallStatus.Disconnected)
{
return new List<CodecActiveCallItem>();
}
else
{
return new List<CodecActiveCallItem>() { CurrentCallItem };
}
}
}
}

View File

@@ -0,0 +1,604 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class Ddvc01VtcMessenger : MessengerBase
{
BasicTriList EISC;
/********* Bools *********/
/// <summary>
/// 724
/// </summary>
const uint BDialHangup = 724;
/// <summary>
/// 750
/// </summary>
const uint BCallIncoming = 750;
/// <summary>
/// 751
/// </summary>
const uint BIncomingAnswer = 751;
/// <summary>
/// 752
/// </summary>
const uint BIncomingReject = 752;
/// <summary>
/// 741
/// </summary>
const uint BSpeedDial1 = 741;
/// <summary>
/// 742
/// </summary>
const uint BSpeedDial2 = 742;
/// <summary>
/// 743
/// </summary>
const uint BSpeedDial3 = 743;
/// <summary>
/// 744
/// </summary>
const uint BSpeedDial4 = 744;
/// <summary>
/// 800
/// </summary>
const uint BDirectorySearchBusy = 800;
/// <summary>
/// 801
/// </summary>
const uint BDirectoryLineSelected = 801;
/// <summary>
/// 801 when selected entry is a contact
/// </summary>
const uint BDirectoryEntryIsContact = 801;
/// <summary>
/// 802 To show/hide back button
/// </summary>
const uint BDirectoryIsRoot = 802;
/// <summary>
/// 803 Pulse from system to inform us when directory is ready
/// </summary>
const uint DDirectoryHasChanged = 803;
/// <summary>
/// 804
/// </summary>
const uint BDirectoryRoot = 804;
/// <summary>
/// 805
/// </summary>
const uint BDirectoryFolderBack = 805;
/// <summary>
/// 806
/// </summary>
const uint BDirectoryDialSelectedLine = 806;
/// <summary>
/// 811
/// </summary>
const uint BCameraControlUp = 811;
/// <summary>
/// 812
/// </summary>
const uint BCameraControlDown = 812;
/// <summary>
/// 813
/// </summary>
const uint BCameraControlLeft = 813;
/// <summary>
/// 814
/// </summary>
const uint BCameraControlRight = 814;
/// <summary>
/// 815
/// </summary>
const uint BCameraControlZoomIn = 815;
/// <summary>
/// 816
/// </summary>
const uint BCameraControlZoomOut = 816;
/// <summary>
/// 821 - 826
/// </summary>
const uint BCameraPresetStart = 821;
/// <summary>
/// 831
/// </summary>
const uint BCameraModeAuto = 831;
/// <summary>
/// 832
/// </summary>
const uint BCameraModeManual = 832;
/// <summary>
/// 833
/// </summary>
const uint BCameraModeOff = 833;
/********* Ushorts *********/
/// <summary>
/// 760
/// </summary>
const uint UCameraNumberSelect = 760;
/// <summary>
/// 801
/// </summary>
const uint UDirectorySelectRow = 801;
/// <summary>
/// 801
/// </summary>
const uint UDirectoryRowCount = 801;
/********* Strings *********/
/// <summary>
/// 701
/// </summary>
const uint SCurrentDialString = 701;
/// <summary>
/// 702
/// </summary>
const uint SCurrentCallName = 702;
/// <summary>
/// 703
/// </summary>
const uint SCurrentCallNumber = 703;
/// <summary>
/// 731
/// </summary>
const uint SHookState = 731;
/// <summary>
/// 722
/// </summary>
const uint SCallDirection = 722;
/// <summary>
/// 751
/// </summary>
const uint SIncomingCallName = 751;
/// <summary>
/// 752
/// </summary>
const uint SIncomingCallNumber = 752;
/// <summary>
/// 800
/// </summary>
const uint SDirectorySearchString = 800;
/// <summary>
/// 801-1055
/// </summary>
const uint SDirectoryEntriesStart = 801;
/// <summary>
/// 1056
/// </summary>
const uint SDirectoryEntrySelectedName = 1056;
/// <summary>
/// 1057
/// </summary>
const uint SDirectoryEntrySelectedNumber = 1057;
/// <summary>
/// 1058
/// </summary>
const uint SDirectorySelectedFolderName = 1058;
/// <summary>
/// 701-712 0-9*#
/// </summary>
Dictionary<string, uint> DTMFMap = new Dictionary<string, uint>
{
{ "1", 701 },
{ "2", 702 },
{ "3", 703 },
{ "4", 704 },
{ "5", 705 },
{ "6", 706 },
{ "7", 707 },
{ "8", 708 },
{ "9", 709 },
{ "0", 710 },
{ "*", 711 },
{ "#", 712 },
};
CodecActiveCallItem CurrentCallItem;
CodecActiveCallItem IncomingCallItem;
ushort PreviousDirectoryLength = 0;
/// <summary>
///
/// </summary>
/// <param name="eisc"></param>
/// <param name="messagePath"></param>
public Ddvc01VtcMessenger(string key, BasicTriList eisc, string messagePath)
: base(key, messagePath)
{
EISC = eisc;
CurrentCallItem = new CodecActiveCallItem();
CurrentCallItem.Type = eCodecCallType.Video;
CurrentCallItem.Id = "-video-";
}
/// <summary>
///
/// </summary>
/// <param name="appServerController"></param>
protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
{
var asc = appServerController;
EISC.SetStringSigAction(SHookState, s =>
{
CurrentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true);
PostFullStatus(); // SendCallsList();
});
EISC.SetStringSigAction(SCurrentCallNumber, s =>
{
CurrentCallItem.Number = s;
PostCallsList();
});
EISC.SetStringSigAction(SCurrentCallName, s =>
{
CurrentCallItem.Name = s;
PostCallsList();
});
EISC.SetStringSigAction(SCallDirection, s =>
{
CurrentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true);
PostCallsList();
});
EISC.SetBoolSigAction(BCallIncoming, b =>
{
if (b)
{
var ica = new CodecActiveCallItem()
{
Direction = eCodecCallDirection.Incoming,
Id = "-video-incoming",
Name = EISC.GetString(SIncomingCallName),
Number = EISC.GetString(SIncomingCallNumber),
Status = eCodecCallStatus.Ringing,
Type = eCodecCallType.Video
};
IncomingCallItem = ica;
}
else
{
IncomingCallItem = null;
}
PostCallsList();
});
// Directory insanity
EISC.SetUShortSigAction(UDirectoryRowCount, u =>
{
// The length of the list comes in before the list does.
// Splice the sig change operation onto the last string sig that will be changing
// when the directory entries make it through.
if (PreviousDirectoryLength > 0)
{
EISC.ClearStringSigAction(SDirectoryEntriesStart + PreviousDirectoryLength - 1);
}
EISC.SetStringSigAction(SDirectoryEntriesStart + u - 1, s => PostDirectory());
PreviousDirectoryLength = u;
});
EISC.SetStringSigAction(SDirectoryEntrySelectedName, s =>
{
PostStatusMessage(new
{
directoryContactSelected = new
{
name = EISC.GetString(SDirectoryEntrySelectedName),
}
});
});
EISC.SetStringSigAction(SDirectoryEntrySelectedNumber, s =>
{
PostStatusMessage(new
{
directoryContactSelected = new
{
number = EISC.GetString(SDirectoryEntrySelectedNumber),
}
});
});
EISC.SetStringSigAction(SDirectorySelectedFolderName, s => PostStatusMessage(new
{
directorySelectedFolderName = EISC.GetString(SDirectorySelectedFolderName)
}));
EISC.SetSigTrueAction(BCameraModeAuto, () => PostCameraMode());
EISC.SetSigTrueAction(BCameraModeManual, () => PostCameraMode());
EISC.SetSigTrueAction(BCameraModeOff, () => PostCameraMode());
EISC.SetUShortSigAction(UCameraNumberSelect, (u) => PostSelectedCamera());
// Add press and holds using helper action
Action<string, uint> addPHAction = (s, u) =>
AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => EISC.SetBool(u, b)));
addPHAction("/cameraUp", BCameraControlUp);
addPHAction("/cameraDown", BCameraControlDown);
addPHAction("/cameraLeft", BCameraControlLeft);
addPHAction("/cameraRight", BCameraControlRight);
addPHAction("/cameraZoomIn", BCameraControlZoomIn);
addPHAction("/cameraZoomOut", BCameraControlZoomOut);
// Add straight pulse calls using helper action
Action<string, uint> addAction = (s, u) =>
AppServerController.AddAction(MessagePath + s, new Action(() => EISC.PulseBool(u, 100)));
addAction("/endCallById", BDialHangup);
addAction("/acceptById", BIncomingAnswer);
addAction("/rejectById", BIncomingReject);
addAction("/speedDial1", BSpeedDial1);
addAction("/speedDial2", BSpeedDial2);
addAction("/speedDial3", BSpeedDial3);
addAction("/speedDial4", BSpeedDial4);
addAction("/cameraModeAuto", BCameraModeAuto);
addAction("/cameraModeManual", BCameraModeManual);
addAction("/cameraModeOff", BCameraModeOff);
asc.AddAction("/cameraSelect", new Action<string>(SelectCamera));
// camera presets
for(uint i = 0; i < 6; i++)
{
addAction("/cameraPreset" + (i + 1), BCameraPresetStart + i);
}
asc.AddAction(MessagePath + "/isReady", new Action(PostIsReady));
// Get status
asc.AddAction(MessagePath + "/fullStatus", new Action(PostFullStatus));
// Dial on string
asc.AddAction(MessagePath + "/dial", new Action<string>(s =>
EISC.SetString(SCurrentDialString, s)));
// Pulse DTMF
asc.AddAction(MessagePath + "/dtmf", new Action<string>(s =>
{
if (DTMFMap.ContainsKey(s))
{
EISC.PulseBool(DTMFMap[s], 100);
}
}));
// Directory madness
asc.AddAction(MessagePath + "/directoryRoot", new Action(() => EISC.PulseBool(BDirectoryRoot)));
asc.AddAction(MessagePath + "/directoryBack", new Action(() => EISC.PulseBool(BDirectoryFolderBack)));
asc.AddAction(MessagePath + "/directoryById", new Action<string>(s =>
{
// the id should contain the line number to forward to simpl
try
{
var u = ushort.Parse(s);
EISC.SetUshort(UDirectorySelectRow, u);
EISC.PulseBool(BDirectoryLineSelected);
}
catch (Exception)
{
Debug.Console(1, this, Debug.ErrorLogLevel.Warning,
"/directoryById request contains non-numeric ID incompatible with DDVC bridge");
}
}));
asc.AddAction(MessagePath + "/directorySelectContact", new Action<string>(s =>
{
try
{
var u = ushort.Parse(s);
EISC.SetUshort(UDirectorySelectRow, u);
EISC.PulseBool(BDirectoryLineSelected);
}
catch
{
}
}));
asc.AddAction(MessagePath + "/directoryDialContact", new Action(() => {
EISC.PulseBool(BDirectoryDialSelectedLine);
}));
asc.AddAction(MessagePath + "/getDirectory", new Action(() =>
{
if (EISC.GetUshort(UDirectoryRowCount) > 0)
{
PostDirectory();
}
else
{
EISC.PulseBool(BDirectoryRoot);
}
}));
}
/// <summary>
///
/// </summary>
void PostFullStatus()
{
this.PostStatusMessage(new
{
calls = GetCurrentCallList(),
cameraMode = GetCameraMode(),
currentCallString = EISC.GetString(SCurrentCallNumber),
currentDialString = EISC.GetString(SCurrentDialString),
directoryContactSelected = new
{
name = EISC.GetString(SDirectoryEntrySelectedName),
number = EISC.GetString(SDirectoryEntrySelectedNumber)
},
directorySelectedFolderName = EISC.GetString(SDirectorySelectedFolderName),
isInCall = EISC.GetString(SHookState) == "Connected",
hasDirectory = true,
hasDirectorySearch = false,
hasRecents = true,
hasCameras = true,
selectedCamera = GetSelectedCamera(),
});
}
/// <summary>
///
/// </summary>
void PostDirectory()
{
var u = EISC.GetUshort(UDirectoryRowCount);
var items = new List<object>();
for (uint i = 0; i < u; i++)
{
var name = EISC.GetString(SDirectoryEntriesStart + i);
var id = (i + 1).ToString();
// is folder or contact?
if (name.StartsWith("[+]"))
{
items.Add(new
{
folderId = id,
name = name
});
}
else
{
items.Add(new
{
contactId = id,
name = name
});
}
}
var directoryMessage = new
{
currentDirectory = new
{
isRootDirectory = EISC.GetBool(BDirectoryIsRoot),
directoryResults = items
}
};
PostStatusMessage(directoryMessage);
}
/// <summary>
///
/// </summary>
void PostCameraMode()
{
PostStatusMessage(new
{
cameraMode = GetCameraMode()
});
}
/// <summary>
///
/// </summary>
/// <param name="mode"></param>
string GetCameraMode()
{
string m;
if (EISC.GetBool(BCameraModeAuto)) m = "auto";
else if (EISC.GetBool(BCameraModeManual)) m = "manual";
else m = "off";
return m;
}
void PostSelectedCamera()
{
PostStatusMessage(new
{
selectedCamera = GetSelectedCamera()
});
}
/// <summary>
///
/// </summary>
string GetSelectedCamera()
{
var num = EISC.GetUshort(UCameraNumberSelect);
string m;
if (num == 100)
{
m = "cameraFar";
}
else
{
m = "camera" + num;
}
return m;
}
/// <summary>
///
/// </summary>
void PostIsReady()
{
PostStatusMessage(new
{
isReady = true
});
}
/// <summary>
///
/// </summary>
void PostCallsList()
{
PostStatusMessage(new
{
calls = GetCurrentCallList(),
});
}
/// <summary>
///
/// </summary>
/// <param name="s"></param>
void SelectCamera(string s)
{
var cam = s.Substring(6);
if (cam.ToLower() == "far")
{
EISC.SetUshort(UCameraNumberSelect, 100);
}
else
{
EISC.SetUshort(UCameraNumberSelect, UInt16.Parse(cam));
}
}
/// <summary>
/// Turns the
/// </summary>
/// <returns></returns>
List<CodecActiveCallItem> GetCurrentCallList()
{
var list = new List<CodecActiveCallItem>();
if (CurrentCallItem.Status != eCodecCallStatus.Disconnected)
{
list.Add(CurrentCallItem);
}
if (EISC.GetBool(BCallIncoming)) {
}
return list;
}
}
}

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Provides a messaging bridge for a VideoCodecBase
/// </summary>
public abstract class MessengerBase : IKeyed
{
public string Key { get; private set; }
/// <summary>
///
/// </summary>
public CotijaSystemController AppServerController { get; private set; }
public string MessagePath { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="codec"></param>
public MessengerBase(string key, string messagePath)
{
Key = key;
if (string.IsNullOrEmpty(messagePath))
throw new ArgumentException("messagePath must not be empty or null");
MessagePath = messagePath;
}
/// <summary>
/// Registers this messenger with appserver controller
/// </summary>
/// <param name="appServerController"></param>
public void RegisterWithAppServer(CotijaSystemController appServerController)
{
if (appServerController == null)
throw new ArgumentNullException("appServerController");
AppServerController = appServerController;
CustomRegisterWithAppServer(AppServerController);
}
/// <summary>
/// Implemented in extending classes. Wire up API calls and feedback here
/// </summary>
/// <param name="appServerController"></param>
abstract protected void CustomRegisterWithAppServer(CotijaSystemController appServerController);
/// <summary>
/// Helper for posting status message
/// </summary>
/// <param name="contentObject">The contents of the content object</param>
protected void PostStatusMessage(object contentObject)
{
if (AppServerController != null)
{
AppServerController.SendMessageToServer(JObject.FromObject(new
{
type = MessagePath,
content = contentObject
}));
}
}
}
}

View File

@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Monitoring;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class SystemMonitorMessenger : MessengerBase
{
public SystemMonitorController SysMon { get; private set; }
public SystemMonitorMessenger(string key, SystemMonitorController sysMon, string messagePath)
: base(key, messagePath)
{
if (sysMon == null)
throw new ArgumentNullException("sysMon");
SysMon = sysMon;
SysMon.SystemMonitorPropertiesChanged += new EventHandler<EventArgs>(SysMon_SystemMonitorPropertiesChanged);
foreach (var p in SysMon.ProgramStatusFeedbackCollection)
{
p.Value.ProgramInfoChanged += new EventHandler<ProgramInfoEventArgs>(ProgramInfoChanged);
}
CrestronConsole.AddNewConsoleCommand(s => SendFullStatusMessage(), "SendFullSysMonStatus", "Sends the full System Monitor Status", ConsoleAccessLevelEnum.AccessOperator);
}
/// <summary>
/// Posts the program information message
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ProgramInfoChanged(object sender, ProgramInfoEventArgs e)
{
if (e.ProgramInfo != null)
{
//Debug.Console(1, "Posting Status Message: {0}", e.ProgramInfo.ToString());
PostStatusMessage(e.ProgramInfo);
}
}
/// <summary>
/// Posts the system monitor properties
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void SysMon_SystemMonitorPropertiesChanged(object sender, EventArgs e)
{
SendSystemMonitorStatusMessage();
}
void SendFullStatusMessage()
{
SendSystemMonitorStatusMessage();
foreach (var p in SysMon.ProgramStatusFeedbackCollection)
{
PostStatusMessage(p.Value.ProgramInfo);
}
}
void SendSystemMonitorStatusMessage()
{
Debug.Console(1, "Posting System Monitor Status Message.");
// This takes a while, launch a new thread
CrestronInvoke.BeginInvoke((o) =>
{
PostStatusMessage(new
{
timeZone = SysMon.TimeZoneFeedback.IntValue,
timeZoneName = SysMon.TimeZoneTextFeedback.StringValue,
ioControllerVersion = SysMon.IOControllerVersionFeedback.StringValue,
snmpVersion = SysMon.SnmpVersionFeedback.StringValue,
bacnetVersion = SysMon.BACnetAppVersionFeedback.StringValue,
controllerVersion = SysMon.ControllerVersionFeedback.StringValue
});
});
}
protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
{
AppServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullStatusMessage));
}
}
}

View File

@@ -13,31 +13,25 @@ using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Provides a messaging bridge for a VideoCodecBase
/// Provides a messaging bridge for a VideoCodecBase device
/// </summary>
public class VideoCodecBaseMessenger
public class VideoCodecBaseMessenger : MessengerBase
{
/// <summary>
///
/// </summary>
public VideoCodecBase Codec { get; private set; }
public CotijaSystemController AppServerController { get; private set; }
public string MessagePath { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="codec"></param>
public VideoCodecBaseMessenger(VideoCodecBase codec, string messagePath)
public VideoCodecBaseMessenger(string key, VideoCodecBase codec, string messagePath)
: base(key, messagePath)
{
if (codec == null)
throw new ArgumentNullException("codec");
if (string.IsNullOrEmpty(messagePath))
throw new ArgumentException("messagePath must not be empty or null");
MessagePath = messagePath;
Codec = codec;
codec.CallStatusChange += new EventHandler<CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
codec.IsReadyChange += new EventHandler<EventArgs>(codec_IsReadyChange);
@@ -46,8 +40,33 @@ namespace PepperDash.Essentials.AppServer.Messengers
if (dirCodec != null)
{
dirCodec.DirectoryResultReturned += new EventHandler<DirectoryEventArgs>(dirCodec_DirectoryResultReturned);
}
var recCodec = codec as IHasCallHistory;
if (recCodec != null)
{
recCodec.CallHistory.RecentCallsListHasChanged += new EventHandler<EventArgs>(CallHistory_RecentCallsListHasChanged);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CallHistory_RecentCallsListHasChanged(object sender, EventArgs e)
{
var recents = (sender as CodecCallHistory).RecentCalls;
if (recents != null)
{
PostStatusMessage(new
{
recentCalls = recents
});
}
}
/// <summary>
///
@@ -56,13 +75,73 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <param name="e"></param>
void dirCodec_DirectoryResultReturned(object sender, DirectoryEventArgs e)
{
var dir = e.Directory;
PostStatusMessage(new
{
currentDirectory = e.Directory
});
SendDirectory((Codec as IHasDirectory).CurrentDirectoryResult, e.DirectoryIsOnRoot);
}
/// <summary>
/// Posts the current directory
/// </summary>
void SendDirectory(CodecDirectory directory, bool isRoot)
{
var dirCodec = Codec as IHasDirectory;
if (dirCodec != null)
{
var prefixedDirectoryResults = PrefixDirectoryFolderItems(directory);
var directoryMessage = new
{
currentDirectory = new
{
directoryResults = prefixedDirectoryResults,
isRootDirectory = isRoot
}
};
PostStatusMessage(directoryMessage);
}
}
/// <summary>
/// Iterates a directory object and prefixes any folder items with "[+] "
/// </summary>
/// <param name="directory"></param>
/// <returns></returns>
List<DirectoryItem> PrefixDirectoryFolderItems (CodecDirectory directory)
{
var tempDirectoryList = new List<DirectoryItem>();
if (directory.CurrentDirectoryResults.Count > 0)
{
foreach (var item in directory.CurrentDirectoryResults)
{
if (item is DirectoryFolder)
{
var newFolder = new DirectoryFolder();
newFolder = (DirectoryFolder)item.Clone();
string prefixName = "[+] " + newFolder.Name;
newFolder.Name = prefixName;
tempDirectoryList.Add(newFolder);
}
else
{
tempDirectoryList.Add(item);
}
}
}
//else
//{
// DirectoryItem noResults = new DirectoryItem() { Name = "No Results Found" };
// tempDirectoryList.Add(noResults);
//}
return tempDirectoryList;
}
/// <summary>
///
/// </summary>
@@ -77,16 +156,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
/// <summary>
/// Registers this codec's messaging with an app server controller
/// Called from base's RegisterWithAppServer method
/// </summary>
/// <param name="appServerController"></param>
public void RegisterWithAppServer(CotijaSystemController appServerController)
protected override void CustomRegisterWithAppServer(CotijaSystemController appServerController)
{
if (appServerController == null)
throw new ArgumentNullException("appServerController");
AppServerController = appServerController;
appServerController.AddAction("/device/videoCodec/isReady", new Action(SendIsReady));
appServerController.AddAction("/device/videoCodec/fullStatus", new Action(SendVtcFullMessageObject));
appServerController.AddAction("/device/videoCodec/dial", new Action<string>(s => Codec.Dial(s)));
@@ -110,9 +184,24 @@ namespace PepperDash.Essentials.AppServer.Messengers
if (call != null)
Codec.AcceptCall(call);
}));
appServerController.AddAction(MessagePath + "/directoryRoot", new Action(GetDirectoryRoot));
appServerController.AddAction(MessagePath + "/directoryById", new Action<string>(s => GetDirectory(s)));
appServerController.AddAction(MessagePath + "/directorySearch", new Action<string>(s => DirectorySearch(s)));
// Directory actions
var dirCodec = Codec as IHasDirectory;
if (dirCodec != null)
{
appServerController.AddAction(MessagePath + "/getDirectory", new Action(GetDirectoryRoot));
appServerController.AddAction(MessagePath + "/directoryById", new Action<string>(s => GetDirectory(s)));
appServerController.AddAction(MessagePath + "/directorySearch", new Action<string>(s => DirectorySearch(s)));
appServerController.AddAction(MessagePath + "/directoryBack", new Action(GetPreviousDirectory));
}
// History actions
var recCodec = Codec as IHasCallHistory;
if (recCodec != null)
{
appServerController.AddAction(MessagePath + "/getCallHistory", new Action(GetCallHistory));
}
appServerController.AddAction(MessagePath + "/privacyModeOn", new Action(Codec.PrivacyModeOn));
appServerController.AddAction(MessagePath + "/privacyModeOff", new Action(Codec.PrivacyModeOff));
appServerController.AddAction(MessagePath + "/privacyModeToggle", new Action(Codec.PrivacyModeToggle));
@@ -122,6 +211,24 @@ namespace PepperDash.Essentials.AppServer.Messengers
appServerController.AddAction(MessagePath + "/standbyOff", new Action(Codec.StandbyDeactivate));
}
void GetCallHistory()
{
var codec = (Codec as IHasCallHistory);
if (codec != null)
{
var recents = codec.CallHistory.RecentCalls;
if (recents != null)
{
PostStatusMessage(new
{
recentCalls = recents
});
}
}
}
public void GetFullStatusMessage()
{
@@ -184,12 +291,28 @@ namespace PepperDash.Essentials.AppServer.Messengers
return;
}
PostStatusMessage(new
{
currentDirectory = dirCodec.DirectoryRoot
});
dirCodec.SetCurrentDirectoryToRoot();
//PostStatusMessage(new
//{
// currentDirectory = dirCodec.DirectoryRoot
//});
}
/// <summary>
/// Requests the parent folder contents
/// </summary>
void GetPreviousDirectory()
{
var dirCodec = Codec as IHasDirectory;
if (dirCodec == null)
{
return;
}
dirCodec.GetDirectoryParentFolderContents();
}
/// <summary>
/// Handler for codec changes
/// </summary>
@@ -239,21 +362,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
sipURI = info.SipUri
},
showSelfViewByDefault = Codec.ShowSelfViewByDefault,
hasDirectory = Codec is IHasDirectory
hasDirectory = Codec is IHasDirectory,
hasDirectorySearch = true,
hasRecents = Codec is IHasCallHistory,
hasCameras = Codec is IHasCameraControl
});
}
/// <summary>
/// Helper for posting status message
/// </summary>
/// <param name="contentObject">The contents of the content object</param>
void PostStatusMessage(object contentObject)
{
AppServerController.SendMessageToServer(JObject.FromObject(new
{
type = MessagePath,
content = contentObject
}));
}
}
}

View File

@@ -10,6 +10,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.AppServer.Messengers;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.Config;
@@ -26,6 +27,14 @@ namespace PepperDash.Essentials.Room.Cotija
/// </summary>
public const uint RoomIsOn = 301;
/// <summary>
/// 41
/// </summary>
public const uint PromptForCode = 41;
/// <summary>
/// 42
/// </summary>
public const uint ClientJoined = 42;
/// <summary>
/// 51
/// </summary>
@@ -47,7 +56,10 @@ namespace PepperDash.Essentials.Room.Cotija
/// 1
/// </summary>
public const uint MasterVolumeMuteToggle = 1;
/// <summary>
/// 1
/// </summary>
public const uint VolumeMutesJoinStart = 1;
/// <summary>
/// 61
/// </summary>
@@ -60,17 +72,23 @@ namespace PepperDash.Essentials.Room.Cotija
/// 63
/// </summary>
public const uint ShutdownStart = 63;
/// <summary>
/// 72
/// </summary>
public const uint SourceHasChanged = 72;
public const uint SourceHasChanged = 71;
/// <summary>
/// 261 - The start of the range of speed dial visibles
/// </summary>
public const uint SpeedDialVisibleStartJoin = 261;
/// <summary>
/// 501
/// </summary>
public const uint ConfigIsReady = 501;
/// <summary>
/// 601
/// </summary>
public const uint SourceShareDisableStartJoin = 601;
}
public class UshortJoin
@@ -79,19 +97,40 @@ namespace PepperDash.Essentials.Room.Cotija
/// 1
/// </summary>
public const uint MasterVolumeLevel = 1;
/// <summary>
/// 1
/// </summary>
public const uint VolumeSlidersJoinStart = 1;
/// <summary>
/// 61
/// </summary>
public const uint ShutdownPromptDuration = 61;
/// <summary>
/// 101
/// </summary>
public const uint VolumeSliderCount = 101;
}
public class StringJoin
{
/// <summary>
/// 1
/// </summary>
public const uint VolumeSliderNamesJoinStart = 1;
/// <summary>
/// 71
/// </summary>
public const uint SelectedSourceKey = 71;
/// <summary>
/// 241
/// </summary>
public const uint SpeedDialNameStartJoin = 241;
/// <summary>
/// 251
/// </summary>
public const uint SpeedDialNumberStartJoin = 251;
/// <summary>
/// 501
@@ -121,6 +160,38 @@ namespace PepperDash.Essentials.Room.Cotija
/// 402
/// </summary>
public const uint ServerUrl = 402;
/// <summary>
/// 512
/// </summary>
public const uint RoomSpeedDialNamesJoinStart = 512;
/// <summary>
/// 516
/// </summary>
public const uint RoomSpeedDialNumberssJoinStart = 516;
/// <summary>
/// 601
/// </summary>
public const uint SourceNameJoinStart = 601;
/// <summary>
/// 621
/// </summary>
public const uint SourceIconJoinStart = 621;
/// <summary>
/// 641
/// </summary>
public const uint SourceKeyJoinStart = 641;
/// <summary>
/// 661
/// </summary>
public const uint SourceTypeJoinStart = 661;
/// <summary>
/// 761
/// </summary>
public const uint CameraNearNameStart = 761;
/// <summary>
/// 770 - presence of this name on the input will cause the camera to be added
/// </summary>
public const uint CameraFarName = 770;
}
/// <summary>
@@ -145,6 +216,9 @@ namespace PepperDash.Essentials.Room.Cotija
CotijaDdvc01DeviceBridge SourceBridge;
Ddvc01AtcMessenger AtcMessenger;
Ddvc01VtcMessenger VtcMessenger;
/// <summary>
///
@@ -182,6 +256,14 @@ namespace PepperDash.Essentials.Room.Cotija
SetupFunctions();
SetupFeedbacks();
var atcKey = string.Format("atc-{0}-{1}", this.Key, Parent.Key);
AtcMessenger = new Ddvc01AtcMessenger(atcKey, EISC, "/device/audioCodec");
AtcMessenger.RegisterWithAppServer(Parent);
var vtcKey = string.Format("atc-{0}-{1}", this.Key, Parent.Key);
VtcMessenger = new Ddvc01VtcMessenger(vtcKey, EISC, "/device/videoCodec");
VtcMessenger.RegisterWithAppServer(Parent);
EISC.SigChange += EISC_SigChange;
EISC.OnlineStatusChange += (o, a) =>
{
@@ -216,8 +298,6 @@ namespace PepperDash.Essentials.Room.Cotija
}
}, "mobilebridgedump", "Dumps DDVC01 bridge EISC data b,u,s", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => LoadConfigValues(), "loadddvc", "", ConsoleAccessLevelEnum.AccessOperator);
return base.CustomActivate();
}
@@ -227,6 +307,8 @@ namespace PepperDash.Essentials.Room.Cotija
/// </summary>
void SetupFunctions()
{
Parent.AddAction(@"/room/room1/promptForCode", new Action(() => EISC.PulseBool(BoolJoin.PromptForCode)));
Parent.AddAction(@"/room/room1/clientJoined", new Action(() => EISC.PulseBool(BoolJoin.ClientJoined)));
Parent.AddAction(@"/room/room1/status", new Action(SendFullStatus));
@@ -238,6 +320,10 @@ namespace PepperDash.Essentials.Room.Cotija
Parent.AddAction(@"/room/room1/defaultsource", new Action(() =>
EISC.PulseBool(BoolJoin.ActivitySharePress)));
Parent.AddAction(@"/room/room1/activityVideo", new Action(() =>
EISC.PulseBool(BoolJoin.ActivityVideoCallPress)));
Parent.AddAction(@"/room/room1/activityPhone", new Action(() =>
EISC.PulseBool(BoolJoin.ActivityPhoneCallPress)));
Parent.AddAction(@"/room/room1/volumes/master/level", new Action<ushort>(u =>
EISC.SetUshort(UshortJoin.MasterVolumeLevel, u)));
@@ -250,20 +336,26 @@ namespace PepperDash.Essentials.Room.Cotija
EISC.PulseBool(BoolJoin.ShutdownEnd)));
Parent.AddAction(@"/room/room1/shutdownCancel", new Action(() =>
EISC.PulseBool(BoolJoin.ShutdownCancel)));
// Source Device (Current Source)'
SourceDeviceMapDictionary sourceJoinMap = new SourceDeviceMapDictionary();
var prefix = @"/device/currentSource/";
foreach (var item in sourceJoinMap)
{
Parent.AddAction(string.Format("{0}{1}", prefix, item.Key), new PressAndHoldAction(b => EISC.SetBool(item.Value, b)));
}
}
/// <summary>
///
/// </summary>
/// <param name="devKey"></param>
void SetupSourceFunctions(string devKey)
{
SourceDeviceMapDictionary sourceJoinMap = new SourceDeviceMapDictionary();
var prefix = string.Format("/device/{0}/", devKey);
foreach (var item in sourceJoinMap)
{
var join = item.Value;
Parent.AddAction(string.Format("{0}{1}", prefix, item.Key), new PressAndHoldAction(b => EISC.SetBool(join, b)));
}
}
/// <summary>
/// Links feedbacks to whatever is gonna happen!
/// </summary>
@@ -345,10 +437,10 @@ namespace PepperDash.Essentials.Room.Cotija
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<DeviceConfig>();
//if (co.Rooms == null)
// always start fresh in case simpl changed
co.Rooms = new List<DeviceConfig>();
var rm = new DeviceConfig();
if (co.Rooms.Count == 0)
{
@@ -360,7 +452,7 @@ 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.Name = EISC.StringOutput[StringJoin.ConfigRoomName].StringValue;
rm.Key = "room1";
rm.Type = "ddvc01";
@@ -371,15 +463,17 @@ namespace PepperDash.Essentials.Room.Cotija
rmProps = JsonConvert.DeserializeObject<DDVC01RoomPropertiesConfig>(rm.Properties.ToString());
rmProps.Help = new EssentialsHelpPropertiesConfig();
rmProps.Help.CallButtonText = EISC.StringOutput[503].StringValue;
rmProps.Help.Message = EISC.StringOutput[502].StringValue;
rmProps.Help.CallButtonText = EISC.StringOutput[StringJoin.ConfigHelpNumber].StringValue;
rmProps.Help.Message = EISC.StringOutput[StringJoin.ConfigHelpMessage].StringValue;
rmProps.Environment = new EssentialsEnvironmentPropertiesConfig(); // enabled defaults to false
rmProps.RoomPhoneNumber = EISC.StringOutput[504].StringValue;
rmProps.RoomURI = EISC.StringOutput[505].StringValue;
rmProps.RoomPhoneNumber = EISC.StringOutput[StringJoin.ConfigRoomPhoneNumber].StringValue;
rmProps.RoomURI = EISC.StringOutput[StringJoin.ConfigRoomURI].StringValue;
rmProps.SpeedDials = new List<DDVC01SpeedDial>();
// add speed dials as long as there are more - up to 4
#warning fix speed dials - 512-515 names, 516-519 numbers
for (uint i = 512; i <= 519; i = i + 2)
{
var num = EISC.StringOutput[i].StringValue;
@@ -388,8 +482,13 @@ namespace PepperDash.Essentials.Room.Cotija
var name = EISC.StringOutput[i + 1].StringValue;
rmProps.SpeedDials.Add(new DDVC01SpeedDial { Number = num, Name = name});
}
// This MAY need a check
rmProps.AudioCodecKey = "audioCodec";
rmProps.VideoCodecKey = "videoCodec";
// volume control names
var volCount = EISC.UShortOutput[701].UShortValue;
var volCount = EISC.UShortOutput[UshortJoin.VolumeSliderCount].UShortValue;
//// use Volumes object or?
//rmProps.VolumeSliderNames = new List<string>();
@@ -403,7 +502,10 @@ namespace PepperDash.Essentials.Room.Cotija
co.Devices = new List<DeviceConfig>();
// clear out previous DDVC devices
co.Devices.RemoveAll(d => d.Key.StartsWith("source-", StringComparison.OrdinalIgnoreCase));
co.Devices.RemoveAll(d =>
d.Key.StartsWith("source-", StringComparison.OrdinalIgnoreCase)
|| d.Key.Equals("audioCodec", StringComparison.OrdinalIgnoreCase)
|| d.Key.Equals("videoCodec", StringComparison.OrdinalIgnoreCase));
rmProps.SourceListKey = "default";
rm.Properties = JToken.FromObject(rmProps);
@@ -414,22 +516,39 @@ namespace PepperDash.Essentials.Room.Cotija
co.SourceLists = new Dictionary<string,Dictionary<string,SourceListItem>>();
var newSl = new Dictionary<string, SourceListItem>();
// add sources...
for (uint i = 0; i<= 19; i++)
// add "none" source if VTC present
if (!string.IsNullOrEmpty(rmProps.VideoCodecKey))
{
var name = EISC.StringOutput[601 + i].StringValue;
var codecOsd = new SourceListItem()
{
Name = "None",
IncludeInSourceList = true,
Order = 1,
Type = eSourceListItemType.Route,
SourceKey = ""
};
newSl.Add("Source-None", codecOsd);
}
// add sources...
for (uint i = 0; i <= 19; i++)
{
var name = EISC.StringOutput[StringJoin.SourceNameJoinStart + 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;
var icon = EISC.StringOutput[StringJoin.SourceIconJoinStart + i].StringValue;
var key = EISC.StringOutput[StringJoin.SourceKeyJoinStart + i].StringValue;
var type = EISC.StringOutput[StringJoin.SourceTypeJoinStart + i].StringValue;
var disableShare = EISC.BooleanOutput[BoolJoin.SourceShareDisableStartJoin + i].BoolValue;
Debug.Console(0, this, "Adding source {0} '{1}'", key, name);
var newSLI = new SourceListItem{
Icon = icon,
Name = name,
Order = (int)i + 1,
Order = (int)i + 10,
SourceKey = key,
Type = eSourceListItemType.Route,
DisableCodecSharing = disableShare,
};
newSl.Add(key, newSLI);
@@ -447,10 +566,111 @@ namespace PepperDash.Essentials.Room.Cotija
Type = type
};
co.Devices.Add(devConf);
if (group.ToLower().StartsWith("settopbox")) // Add others here as needed
{
SetupSourceFunctions(key);
}
}
co.SourceLists.Add("default", newSl);
// build "audioCodec" config if we need
if (!string.IsNullOrEmpty(rmProps.AudioCodecKey))
{
var acFavs = new List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem>();
for (uint i = 0; i < 4; i++)
{
if (!EISC.GetBool(BoolJoin.SpeedDialVisibleStartJoin + i))
{
break;
}
acFavs.Add(new PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem()
{
Name = EISC.GetString(StringJoin.SpeedDialNameStartJoin + i),
Number = EISC.GetString(StringJoin.SpeedDialNumberStartJoin + i),
Type = PepperDash.Essentials.Devices.Common.Codec.eCodecCallType.Audio
});
}
var acProps = new
{
favorites = acFavs
};
var acStr = "audioCodec";
var acConf = new DeviceConfig()
{
Group = acStr,
Key = acStr,
Name = acStr,
Type = acStr,
Properties = JToken.FromObject(acProps)
};
co.Devices.Add(acConf);
}
if (!string.IsNullOrEmpty(rmProps.VideoCodecKey))
{
#warning Break out these video codec favs
var favs = new List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem>();
for (uint i = 0; i < 4; i++)
{
if (!EISC.GetBool(BoolJoin.SpeedDialVisibleStartJoin + i))
{
break;
}
favs.Add(new PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem()
{
Name = EISC.GetString(StringJoin.SpeedDialNameStartJoin + i),
Number = EISC.GetString(StringJoin.SpeedDialNumberStartJoin + i),
Type = PepperDash.Essentials.Devices.Common.Codec.eCodecCallType.Audio
});
}
// cameras
var camsProps = new List<object>();
for (uint i = 0; i < 9; i++)
{
var name = EISC.GetString(i + StringJoin.CameraNearNameStart);
if (!string.IsNullOrEmpty(name))
{
camsProps.Add(new
{
name = name,
selector = "camera" + (i + 1),
});
}
}
var farName = EISC.GetString(StringJoin.CameraFarName);
if (!string.IsNullOrEmpty(farName))
{
camsProps.Add(new
{
name = farName,
selector = "cameraFar",
});
}
var props = new
{
favorites = favs,
cameras = camsProps,
};
var str = "videoCodec";
var conf = new DeviceConfig()
{
Group = str,
Key = str,
Name = str,
Type = str,
Properties = JToken.FromObject(props)
};
co.Devices.Add(conf);
}
Debug.Console(0, this, "******* CONFIG FROM DDVC: \r{0}", JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented));
var handler = ConfigurationIsReady;
@@ -462,6 +682,9 @@ namespace PepperDash.Essentials.Room.Cotija
ConfigIsLoaded = true;
}
/// <summary>
///
/// </summary>
void SendFullStatus()
{
if (ConfigIsLoaded)
@@ -585,86 +808,5 @@ namespace PepperDash.Essentials.Room.Cotija
EISC.StringInput[StringJoin.UserCodeToSystem].StringValue = UserCode;
EISC.StringInput[StringJoin.ServerUrl].StringValue = Parent.Config.ClientAppUrl;
}
/// <summary>
///
/// </summary>
/// <param name="oldKey"></param>
/// <param name="newKey"></param>
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);
// }
//}
}
}
}

View File

@@ -12,6 +12,7 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Room.Cotija;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
namespace PepperDash.Essentials
{
@@ -22,6 +23,9 @@ namespace PepperDash.Essentials
public VideoCodecBaseMessenger VCMessenger { get; private set; }
public AudioCodecBaseMessenger ACMessenger { get; private set; }
/// <summary>
///
/// </summary>
@@ -74,7 +78,7 @@ namespace PepperDash.Essentials
{
Parent.AddAction(string.Format(@"/room/{0}/volumes/master/level", Room.Key), new Action<ushort>(u =>
(volumeRoom.CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(u)));
Parent.AddAction(string.Format(@"/room/{0}/volumes/master/mute", Room.Key), new Action(() =>
Parent.AddAction(string.Format(@"/room/{0}/volumes/master/muteToggle", Room.Key), new Action(() =>
volumeRoom.CurrentVolumeControls.MuteToggle()));
volumeRoom.CurrentVolumeDeviceChange += new EventHandler<VolumeDeviceChangeEventArgs>(Room_CurrentVolumeDeviceChange);
@@ -82,7 +86,7 @@ namespace PepperDash.Essentials
var currentVolumeDevice = volumeRoom.CurrentVolumeControls as IBasicVolumeWithFeedback;
if (currentVolumeDevice != null)
{
currentVolumeDevice.MuteFeedback.OutputChange += VolumeLevelFeedback_OutputChange;
currentVolumeDevice.MuteFeedback.OutputChange += MuteFeedback_OutputChange;
currentVolumeDevice.VolumeLevelFeedback.OutputChange += VolumeLevelFeedback_OutputChange;
}
}
@@ -92,29 +96,25 @@ namespace PepperDash.Essentials
sscRoom.CurrentSingleSourceChange += new SourceInfoChangeHandler(Room_CurrentSingleSourceChange);
var vcRoom = Room as IHasVideoCodec;
if (vcRoom != null)
if (vcRoom != null && vcRoom.VideoCodec != null)
{
var codec = vcRoom.VideoCodec;
VCMessenger = new VideoCodecBaseMessenger(vcRoom.VideoCodec, "/device/videoCodec");
var key = vcRoom.VideoCodec.Key + "-" + parent.Key;
VCMessenger = new VideoCodecBaseMessenger(key, vcRoom.VideoCodec, "/device/videoCodec");
VCMessenger.RegisterWithAppServer(Parent);
// May need to move this or remove this
codec.CallStatusChange += new EventHandler<CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
vcRoom.IsSharingFeedback.OutputChange += new EventHandler<FeedbackEventArgs>(IsSharingFeedback_OutputChange);
//Parent.AddAction("/device/videoCodec/dial", new Action<string>(s => codec.Dial(s)));
//Parent.AddAction("/device/videoCodec/endCall", new Action<string>(s =>
//{
// var call = codec.ActiveCalls.FirstOrDefault(c => c.Id == s);
// if (call != null)
// {
// codec.EndCall(call);
// }
//}));
//Parent.AddAction("/device/videoCodec/endAllCalls", new Action(() => codec.EndAllCalls()));
}
var acRoom = Room as IHasAudioCodec;
if (acRoom != null && acRoom.AudioCodec != null)
{
var codec = acRoom.AudioCodec;
var key = acRoom.AudioCodec.Key + "-" + parent.Key;
ACMessenger = new AudioCodecBaseMessenger(key, acRoom.AudioCodec, "/device/audioCodec");
ACMessenger.RegisterWithAppServer(Parent);
}
var defCallRm = Room as IRunDefaultCallRoute;
if (defCallRm != null)
{
@@ -169,18 +169,18 @@ namespace PepperDash.Essentials
});
}
/// <summary>
/// Handler for codec changes
/// </summary>
void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
{
PostStatusMessage(new
{
calls = GetCallsMessageObject(),
//vtc = GetVtcCallsMessageObject()
});
///// <summary>
///// Handler for codec changes
///// </summary>
//void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
//{
// PostStatusMessage(new
// {
// calls = GetCallsMessageObject(),
// //vtc = GetVtcCallsMessageObject()
// });
}
//}
/// <summary>
/// Helper for posting status message
@@ -425,53 +425,52 @@ namespace PepperDash.Essentials
PostStatusMessage(new
{
calls = GetCallsMessageObject(),
//calls = GetCallsMessageObject(),
isOn = room.OnFeedback.BoolValue,
selectedSourceKey = sourceKey,
vtc = GetVtcCallsMessageObject(),
//vtc = GetVtcCallsMessageObject(),
volumes = volumes
});
}
/// <summary>
/// Helper to return a anonymous object with the call data for JSON message
/// </summary>
/// <returns></returns>
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
};
}
///// <summary>
///// Helper to return a anonymous object with the call data for JSON message
///// </summary>
///// <returns></returns>
//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
// };
//}
/// <summary>
/// Helper method to build call status for vtc
/// </summary>
/// <returns></returns>
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;
}
///// <summary>
///// Helper method to build call status for vtc
///// </summary>
///// <returns></returns>
//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;
//}
}
/// <summary>

View File

@@ -5,9 +5,17 @@ using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.EthernetCommunication;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Lighting;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.CrestronIO;
using PepperDash.Essentials.DM;
//using PepperDash.Essentials.Devices.Common.Cameras;
namespace PepperDash.Essentials.Bridges
{
@@ -44,17 +52,93 @@ namespace PepperDash.Essentials.Bridges
/// </summary>
public class EiscApi : BridgeApi
{
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; }
public EiscApi(string key, uint ipid, string hostname) :
base(key)
public EiscApi(DeviceConfig dc) :
base(dc.Key)
{
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(ipid, hostname, Global.ControlSystem);
PropertiesConfig = JsonConvert.DeserializeObject<EiscApiPropertiesConfig>(dc.Properties.ToString());
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(PropertiesConfig.Control.IpIdInt, PropertiesConfig.Control.TcpSshProperties.Address, Global.ControlSystem);
Eisc.SigChange += new Crestron.SimplSharpPro.DeviceSupport.SigEventHandler(Eisc_SigChange);
Eisc.Register();
AddPostActivationAction( () =>
{
Debug.Console(1, this, "Linking Devices...");
foreach (var d in PropertiesConfig.Devices)
{
var device = DeviceManager.GetDeviceForKey(d.DeviceKey);
if (device != null)
{
if (device is PepperDash.Essentials.Core.Monitoring.SystemMonitorController)
{
(device as PepperDash.Essentials.Core.Monitoring.SystemMonitorController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is GenericComm)
{
(device as GenericComm).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
//else if (device is CameraBase)
//{
// (device as CameraBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
// continue;
//}
//else if (device is PepperDash.Essentials.Core.TwoWayDisplayBase)
//{
// (device as TwoWayDisplayBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
// continue;
//}
else if (device is DmChassisController)
{
(device as DmChassisController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is DmTxControllerBase)
{
(device as DmTxControllerBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is DmRmcControllerBase)
{
(device as DmRmcControllerBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is GenericRelayDevice)
{
(device as GenericRelayDevice).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is IDigitalInput)
{
(device as IDigitalInput).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
//else if (device is LightingBase)
//{
// (device as LightingBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
// continue;
//}
//else if (device is DigitalLogger)
//{
// (device as DigitalLogger).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
// continue;
//}
}
}
Debug.Console(1, this, "Devices Linked.");
});
}
/// <summary>
@@ -65,7 +149,7 @@ namespace PepperDash.Essentials.Bridges
void Eisc_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
{
if (Debug.Level >= 1)
Debug.Console(1, this, "BridgeApi EISC change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
Debug.Console(1, this, "EiscApi change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
var uo = args.Sig.UserObject;
if (uo is Action<bool>)
(uo as Action<bool>)(args.Sig.BoolValue);
@@ -76,138 +160,27 @@ namespace PepperDash.Essentials.Bridges
}
}
/// <summary>
/// Defines each type and it's matching API type
/// </summary>
public static class DeviceApiFactory
public class EiscApiPropertiesConfig
{
public static Dictionary<Type, Type> TypeMap = new Dictionary<Type, Type>
[JsonProperty("control")]
public EssentialsControlPropertiesConfig Control { get; set; }
[JsonProperty("devices")]
public List<ApiDevice> Devices { get; set; }
public class ApiDevice
{
{ typeof(DmChassisController), typeof(DmChassisControllerApi) },
{ typeof(IBasicCommunication), typeof(IBasicCommunicationApi) }
//{ typeof(SomeShittyDisplayController), typeof(SomeShittyDisplayControllerApi) }
};
}
[JsonProperty("deviceKey")]
public string DeviceKey { get; set; }
[JsonProperty("joinStart")]
public uint JoinStart { get; set; }
/// <summary>
/// API class for IBasicCommunication devices
/// </summary>
public class IBasicCommunicationApi : DeviceApiBase
{
public IBasicCommunication Device { get; set; }
SerialFeedback TextReceivedFeedback;
public IBasicCommunicationApi(IBasicCommunication dev)
{
TextReceivedFeedback = new SerialFeedback();
Device = dev;
SetupFeedbacks();
ActionApi = new Dictionary<string, Object>
{
{ "connect", new Action(Device.Connect) },
{ "disconnect", new Action(Device.Disconnect) },
{ "connectstate", new Action<bool>( b => ConnectByState(b) ) },
{ "sendtext", new Action<string>( s => Device.SendText(s) ) }
};
FeedbackApi = new Dictionary<string, Feedback>
{
{ "isconnected", new BoolFeedback( () => Device.IsConnected ) },
{ "textrecieved", TextReceivedFeedback }
};
[JsonProperty("joinMapKey")]
public string JoinMapKey { get; set; }
}
/// <summary>
/// Controls connection based on state of input
/// </summary>
/// <param name="state"></param>
void ConnectByState(bool state)
{
if (state)
Device.Connect();
else
Device.Disconnect();
}
void SetupFeedbacks()
{
Device.TextReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(Device_TextReceived);
if(Device is ISocketStatus)
(Device as ISocketStatus).ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(IBasicCommunicationApi_ConnectionChange);
}
void IBasicCommunicationApi_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
{
FeedbackApi["isconnected"].FireUpdate();
}
void Device_TextReceived(object sender, GenericCommMethodReceiveTextArgs e)
{
TextReceivedFeedback.FireUpdate(e.Text);
}
}
public class DmChassisController : Device
{
public DmChassisController(string key)
: base(key)
{
}
public void SetInput(int input)
{
Debug.Console(2, this, "Dm Chassis {0}, input {1}", Key, input);
}
}
/// <summary>
/// Each flavor of API is a static class with static properties and a static constructor that
/// links up the things to do.
/// </summary>
public class DmChassisControllerApi : DeviceApiBase
{
IntFeedback Output1Feedback;
IntFeedback Output2Feedback;
public DmChassisControllerApi(DmChassisController dev)
{
Output1Feedback = new IntFeedback( new Func<int>(() => 1));
Output2Feedback = new IntFeedback( new Func<int>(() => 2));
ActionApi = new Dictionary<string, Object>
{
};
FeedbackApi = new Dictionary<string, Feedback>
{
{ "Output-1/fb", Output1Feedback },
{ "Output-2/fb", Output2Feedback }
};
}
/// <summary>
/// Factory method
/// </summary>
/// <param name="dev"></param>
/// <returns></returns>
public static DmChassisControllerApi GetActionApiForDevice(DmChassisController dev)
{
return new DmChassisControllerApi(dev);
}
}

View File

@@ -9,176 +9,133 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Core;
using PepperDash.Essentials.Core.Routing;
using PepperDash.Essentials.Bridges;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.EthernetCommunication;
namespace PepperDash.Essentials
{
public class BridgeFactory
{
public static IKeyed GetDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
{
// ? why is this static JTA 2018-06-13?
public class BridgeFactory
{
public static IKeyed GetDevice(DeviceConfig dc)
{
// ? why is this static JTA 2018-06-13?
var key = dc.Key;
var name = dc.Name;
var type = dc.Type;
var properties = dc.Properties;
var propAnon = new { };
JsonConvert.DeserializeAnonymousType(dc.Properties.ToString(), propAnon);
var key = dc.Key;
var name = dc.Name;
var type = dc.Type;
var properties = dc.Properties;
var propAnon = new { };
var typeName = dc.Type.ToLower();
var groupName = dc.Group.ToLower();
var typeName = dc.Type.ToLower();
var groupName = dc.Group.ToLower();
Debug.Console(0, "Name {0}, Key {1}, Type {2}, Properties {3}", name, key, type, properties.ToString());
if (typeName == "dm")
{
return new DmBridge(key, name, properties);
//Debug.Console(2, "Name {0}, Key {1}, Type {2}, Properties {3}", name, key, type, properties.ToString());
if (typeName == "eiscapi")
{
return new EiscApi(dc);
}
return null;
}
}
public class CommBridge : Device
{
public CommBridgeProperties Properties { get; private set; }
public List<IBasicCommunication> CommDevices { get; private set; }
public CommBridge(string key, string name, JToken properties)
: base(key, name)
{
Properties = JsonConvert.DeserializeObject<CommBridgeProperties>(properties.ToString());
}
public override bool CustomActivate()
{
// Create EiscApis
if (Properties.Eiscs != null)
{
foreach (var eisc in Properties.Eiscs)
{
var ApiEisc = new BridgeApiEisc(eisc.IpId, eisc.Hostname);
}
else if (typeName == "comm")
{
return new CommBridge(key, name, properties);
}
else
return null;
}
}
public class DmBridge : Device
{
public EiscBridgeProperties Properties { get; private set; }
foreach (var deviceKey in Properties.CommDevices)
{
var device = DeviceManager.GetDeviceForKey(deviceKey);
public PepperDash.Essentials.DM.DmChassisController DmSwitch { get; private set; }
public DmBridge(string key, string name, JToken properties) : base(key, name)
{
Properties = JsonConvert.DeserializeObject<EiscBridgeProperties>(properties.ToString());
}
public override bool CustomActivate()
{
// Create EiscApis
if (Properties.Eiscs != null)
{
foreach (var eisc in Properties.Eiscs)
{
var ApiEisc = new BridgeApiEisc(eisc.IpId, eisc.Hostname);
ApiEisc.Eisc.SetUShortSigAction(101, u => DmSwitch.ExecuteSwitch(u,1, eRoutingSignalType.Video));
ApiEisc.Eisc.SetUShortSigAction(102, u => DmSwitch.ExecuteSwitch(u,2, eRoutingSignalType.Video));
}
if (device != null)
{
Debug.Console(0, "deviceKey {0} Found in Device Manager", device.Key);
CommDevices.Add(device as IBasicCommunication);
}
foreach (var device in DeviceManager.AllDevices)
{
if (device.Key == this.Properties.ParentDeviceKey)
{
Debug.Console(0, "deviceKey {0} Matches", device.Key);
DmSwitch = DeviceManager.GetDeviceForKey(device.Key) as PepperDash.Essentials.DM.DmChassisController;
}
else
{
Debug.Console(0, "deviceKey {0} doesn't match", device.Key);
}
else
{
Debug.Console(0, "deviceKey {0} Not Found in Device Manager", deviceKey);
}
Debug.Console(0, "Bridge {0} Activated", this.Name);
return true;
}
// Iterate through all the CommDevices and link up their Actions and Feedbacks
Debug.Console(0, "Bridge {0} Activated", this.Name);
return true;
}
public class CommBridge : Device
{
public CommBridgeProperties Properties { get; private set; }
public List<IBasicCommunication> CommDevices { get; private set; }
public CommBridge(string key, string name, JToken properties)
: base(key, name)
{
Properties = JsonConvert.DeserializeObject<CommBridgeProperties>(properties.ToString());
}
public override bool CustomActivate()
{
// Create EiscApis
if (Properties.Eiscs != null)
{
foreach (var eisc in Properties.Eiscs)
{
var ApiEisc = new BridgeApiEisc(eisc.IpId, eisc.Hostname);
}
}
foreach (var deviceKey in Properties.CommDevices)
{
var device = DeviceManager.GetDeviceForKey(deviceKey);
if (device != null)
{
Debug.Console(0, "deviceKey {0} Found in Device Manager", device.Key);
CommDevices.Add(device as IBasicCommunication);
}
else
{
Debug.Console(0, "deviceKey {0} Not Found in Device Manager", deviceKey);
}
}
// Iterate through all the CommDevices and link up their Actions and Feedbacks
Debug.Console(0, "Bridge {0} Activated", this.Name);
return true;
}
}
}
public class EiscBridgeProperties
{
public string ParentDeviceKey { get; set; }
public eApiType ApiType { get; set; }
public List<EiscProperties> Eiscs { get; set; }
public string ApiOverrideFilePath { get; set; }
public class EiscBridgeProperties
{
public string ParentDeviceKey { get; set; }
public eApiType ApiType { get; set; }
public List<EiscProperties> Eiscs { get; set; }
public string ApiOverrideFilePath { get; set; }
public class EiscProperties
{
public string IpId { get; set; }
public string Hostname { get; set; }
}
public class EiscProperties
{
public string IpId { get; set; }
public string Hostname { get; set; }
}
}
public class CommBridgeProperties : EiscBridgeProperties
{
public List<string> CommDevices { get; set; }
}
public class CommBridgeProperties : EiscBridgeProperties
{
public List<string> CommDevices { get; set; }
}
public enum eApiType { Eisc = 0 }
public enum eApiType { Eisc = 0 }
public class BridgeApiEisc
{
public uint Ipid { get; private set; }
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; }
public class BridgeApiEisc
{
public uint Ipid { get; private set; }
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; }
public BridgeApiEisc(string ipid, string hostname)
{
Ipid = (UInt32)int.Parse(ipid, System.Globalization.NumberStyles.HexNumber);
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(Ipid, hostname, Global.ControlSystem);
Eisc.Register();
Eisc.SigChange += Eisc_SigChange;
Debug.Console(0, "BridgeApiEisc Created at Ipid {0}", ipid);
}
void Eisc_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
{
if (Debug.Level >= 1)
Debug.Console(1, "BridgeApiEisc change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
var uo = args.Sig.UserObject;
if (uo is Action<bool>)
(uo as Action<bool>)(args.Sig.BoolValue);
else if (uo is Action<ushort>)
(uo as Action<ushort>)(args.Sig.UShortValue);
else if (uo is Action<string>)
(uo as Action<string>)(args.Sig.StringValue);
}
public BridgeApiEisc(string ipid, string hostname)
{
Ipid = (UInt32)int.Parse(ipid, System.Globalization.NumberStyles.HexNumber);
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(Ipid, hostname, Global.ControlSystem);
Eisc.Register();
Eisc.SigChange += Eisc_SigChange;
Debug.Console(0, "BridgeApiEisc Created at Ipid {0}", ipid);
}
}
void Eisc_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
{
if (Debug.Level >= 1)
Debug.Console(1, "BridgeApiEisc change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
var uo = args.Sig.UserObject;
if (uo is Action<bool>)
(uo as Action<bool>)(args.Sig.BoolValue);
else if (uo is Action<ushort>)
(uo as Action<ushort>)(args.Sig.UShortValue);
else if (uo is Action<string>)
(uo as Action<string>)(args.Sig.StringValue);
}
}
}

View File

@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Core;
using PepperDash.Essentials.Core.Routing;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Essentials.Bridges;
namespace PepperDash.Essentials {
public class BridgeFactory {
public static IKeyed GetDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc) {
// ? why is this static JTA 2018-06-13?
var key = dc.Key;
var name = dc.Name;
var type = dc.Type;
var properties = dc.Properties;
var propAnon = new { };
JsonConvert.DeserializeAnonymousType(dc.Properties.ToString(), propAnon);
var typeName = dc.Type.ToLower();
var groupName = dc.Group.ToLower();
Debug.Console(2, "Name {0}, Key {1}, Type {2}, Properties {3}", name, key, type, properties.ToString());
if (typeName == "essentialdm")
{
return new EssentialDM(key, name, properties);
}
else if (typeName == "essentialcomm")
{
Debug.Console(2, "Launch Essential Comm");
return new EssentialComm(key, name, properties);
}
else if (typeName == "essentialdsp")
{
Debug.Console(2, "Launch EssentialDsp");
return new EssentialDsp(key, name, properties);
}
else if (typeName == "essentialstvone")
{
Debug.Console(2, "Launch essentialstvone");
return new EssentialsTVOne(key, name, properties);
}
else if (typeName == "essentialslighting")
{
Debug.Console(2, "Launch essentialslighting");
return new EssentialsLightsBridge(key, name, properties);
}
else if (typeName == "eiscapi")
{
return new EiscApi(dc);
}
return null;
}
}
public class BridgeApiEisc {
public uint Ipid;
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc;
public BridgeApiEisc(string ipid) {
Ipid = (UInt32)int.Parse(ipid, System.Globalization.NumberStyles.HexNumber);
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(Ipid, "127.0.0.2", Global.ControlSystem);
Eisc.Register();
Eisc.SigChange += Eisc_SigChange;
Debug.Console(2, "BridgeApiEisc Created at Ipid {0}", ipid);
}
void Eisc_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args) {
if (Debug.Level >= 1)
Debug.Console(2, "DDVC EISC change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
var uo = args.Sig.UserObject;
if (uo is Action<bool>)
(uo as Action<bool>)(args.Sig.BoolValue);
else if (uo is Action<ushort>)
(uo as Action<ushort>)(args.Sig.UShortValue);
else if (uo is Action<string>)
(uo as Action<string>)(args.Sig.StringValue);
}
}
}

View File

@@ -0,0 +1,187 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharpPro.DeviceSupport;
//using PepperDash.Core;
//using PepperDash.Essentials.Core;
//using PepperDash.Essentials.Devices.Common;
//namespace PepperDash.Essentials.Bridges
//{
// public static class CameraControllerApiExtensions
// {
// public static BasicTriList _TriList;
// public static CameraControllerJoinMap JoinMap;
// public static void LinkToApi(this PepperDash.Essentials.Devices.Common.Cameras.CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey)
// {
// JoinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as CameraControllerJoinMap;
// _TriList = trilist;
// if (JoinMap == null)
// {
// JoinMap = new CameraControllerJoinMap();
// }
// JoinMap.OffsetJoinNumbers(joinStart);
// Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Debug.Console(0, "Linking to Bridge Type {0}", cameraDevice.GetType().Name.ToString());
// var commMonitor = cameraDevice as ICommunicationMonitor;
// commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[JoinMap.IsOnline]);
// trilist.SetBoolSigAction(JoinMap.Left, (b) =>
// {
// if (b)
// {
// cameraDevice.PanLeft();
// }
// else
// {
// cameraDevice.Stop();
// }
// });
// trilist.SetBoolSigAction(JoinMap.Right, (b) =>
// {
// if (b)
// {
// cameraDevice.PanRight();
// }
// else
// {
// cameraDevice.Stop();
// }
// });
// trilist.SetBoolSigAction(JoinMap.Up, (b) =>
// {
// if (b)
// {
// cameraDevice.TiltUp();
// }
// else
// {
// cameraDevice.Stop();
// }
// });
// trilist.SetBoolSigAction(JoinMap.Down, (b) =>
// {
// if (b)
// {
// cameraDevice.TiltDown();
// }
// else
// {
// cameraDevice.Stop();
// }
// });
// trilist.SetBoolSigAction(JoinMap.ZoomIn, (b) =>
// {
// if (b)
// {
// cameraDevice.ZoomIn();
// }
// else
// {
// cameraDevice.Stop();
// }
// });
// trilist.SetBoolSigAction(JoinMap.ZoomOut, (b) =>
// {
// if (b)
// {
// cameraDevice.ZoomOut();
// }
// else
// {
// cameraDevice.Stop();
// }
// });
// if (cameraDevice.GetType().Name.ToString().ToLower() == "cameravisca")
// {
// var viscaCamera = cameraDevice as PepperDash.Essentials.Devices.Common.Cameras.CameraVisca;
// trilist.SetSigTrueAction(JoinMap.PowerOn, () => viscaCamera.PowerOn());
// trilist.SetSigTrueAction(JoinMap.PowerOff, () => viscaCamera.PowerOff());
// viscaCamera.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[JoinMap.PowerOn]);
// viscaCamera.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[JoinMap.PowerOff]);
// viscaCamera.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[JoinMap.IsOnline]);
// for (int i = 0; i < JoinMap.NumberOfPresets; i++)
// {
// int tempNum = i;
// trilist.SetSigTrueAction((ushort)(JoinMap.PresetRecallOffset + tempNum), () =>
// {
// viscaCamera.RecallPreset(tempNum);
// });
// trilist.SetSigTrueAction((ushort)(JoinMap.PresetSaveOffset + tempNum), () =>
// {
// viscaCamera.SavePreset(tempNum);
// });
// }
// }
// }
// }
// public class CameraControllerJoinMap : JoinMapBase
// {
// public uint IsOnline { get; set; }
// public uint PowerOff { get; set; }
// public uint PowerOn { get; set; }
// public uint Up { get; set; }
// public uint Down { get; set; }
// public uint Left { get; set; }
// public uint Right { get; set; }
// public uint ZoomIn { get; set; }
// public uint ZoomOut { get; set; }
// public uint PresetRecallOffset { get; set; }
// public uint PresetSaveOffset { get; set; }
// public uint NumberOfPresets { get; set; }
// public CameraControllerJoinMap()
// {
// // Digital
// IsOnline = 9;
// PowerOff = 8;
// PowerOn = 7;
// Up = 1;
// Down = 2;
// Left = 3;
// Right = 4;
// ZoomIn = 5;
// ZoomOut = 6;
// PresetRecallOffset = 10;
// PresetSaveOffset = 30;
// NumberOfPresets = 5;
// // Analog
// }
// public override void OffsetJoinNumbers(uint joinStart)
// {
// var joinOffset = joinStart - 1;
// IsOnline = IsOnline + joinOffset;
// PowerOff = PowerOff + joinOffset;
// PowerOn = PowerOn + joinOffset;
// Up = Up + joinOffset;
// Down = Down + joinOffset;
// Left = Left + joinOffset;
// Right = Right + joinOffset;
// ZoomIn = ZoomIn + joinOffset;
// ZoomOut = ZoomOut + joinOffset;
// PresetRecallOffset = PresetRecallOffset + joinOffset;
// PresetSaveOffset = PresetSaveOffset + joinOffset;
// }
// }
//}

View File

@@ -0,0 +1,77 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharpPro.DeviceSupport;
//using PepperDash.Core;
//using PepperDash.Essentials.Core;
//using PepperDash.Essentials.Devices.Common;
//namespace PepperDash.Essentials.Bridges
//{
// public static class DigitalLoggerApiExtensions
// {
// public static void LinkToApi(this DigitalLogger DigitalLogger, BasicTriList trilist, uint joinStart, string joinMapKey)
// {
// var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DigitalLoggerJoinMap;
// if (joinMap == null)
// joinMap = new DigitalLoggerJoinMap();
// joinMap.OffsetJoinNumbers(joinStart);
// Debug.Console(1, DigitalLogger, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// for (uint i = 1; i <= DigitalLogger.CircuitCount; i++)
// {
// var circuit = i;
// DigitalLogger.CircuitNameFeedbacks[circuit - 1].LinkInputSig(trilist.StringInput[joinMap.CircuitNames + circuit]);
// DigitalLogger.CircuitIsCritical[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitIsCritical + circuit]);
// DigitalLogger.CircuitState[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitState + circuit]);
// trilist.SetSigTrueAction(joinMap.CircuitCycle + circuit, () => DigitalLogger.CycleCircuit(circuit - 1));
// trilist.SetSigTrueAction(joinMap.CircuitOnCmd + circuit, () => DigitalLogger.TurnOnCircuit(circuit - 1));
// trilist.SetSigTrueAction(joinMap.CircuitOffCmd + circuit, () => DigitalLogger.TurnOffCircuit(circuit - 1));
// }
// }
// }
// public class DigitalLoggerJoinMap : JoinMapBase
// {
// public uint IsOnline { get; set; }
// public uint CircuitNames { get; set; }
// public uint CircuitState { get; set; }
// public uint CircuitCycle { get; set; }
// public uint CircuitIsCritical { get; set; }
// public uint CircuitOnCmd { get; set; }
// public uint CircuitOffCmd { get; set; }
// public DigitalLoggerJoinMap()
// {
// // Digital
// IsOnline = 9;
// CircuitState = 0;
// CircuitCycle = 0;
// CircuitIsCritical = 10;
// CircuitOnCmd = 10;
// CircuitOffCmd = 20;
// // Serial
// CircuitNames = 0;
// // Analog
// }
// public override void OffsetJoinNumbers(uint joinStart)
// {
// var joinOffset = joinStart - 1;
// IsOnline = IsOnline + joinOffset;
// CircuitNames = CircuitNames + joinOffset;
// CircuitState = CircuitState + joinOffset;
// CircuitCycle = CircuitCycle + joinOffset;
// CircuitIsCritical = CircuitIsCritical + joinOffset;
// CircuitOnCmd = CircuitOnCmd + joinOffset;
// CircuitOffCmd = CircuitOffCmd + joinOffset;
// }
// }
//}

View File

@@ -0,0 +1,171 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharpPro.DeviceSupport;
//using PepperDash.Core;
//using PepperDash.Essentials.Core;
//using PepperDash.Essentials.Devices.Common;
//namespace PepperDash.Essentials.Bridges
//{
// public static class DisplayControllerApiExtensions
// {
// public static BasicTriList _TriList;
// public static DisplayControllerJoinMap JoinMap;
// public static int InputNumber;
// public static IntFeedback InputNumberFeedback;
// public static List<string> InputKeys = new List<string>();
// public static void LinkToApi(this PepperDash.Essentials.Core.TwoWayDisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey)
// {
// JoinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DisplayControllerJoinMap;
// _TriList = trilist;
// if (JoinMap == null)
// {
// JoinMap = new DisplayControllerJoinMap();
// }
// JoinMap.OffsetJoinNumbers(joinStart);
// Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Debug.Console(0, "Linking to Bridge Type {0}", displayDevice.GetType().Name.ToString());
// trilist.StringInput[JoinMap.Name].StringValue = displayDevice.GetType().Name.ToString();
// InputNumberFeedback = new IntFeedback(() => { return InputNumber;});
// InputNumberFeedback.LinkInputSig(trilist.UShortInput[JoinMap.InputSelect]);
// var commMonitor = displayDevice as ICommunicationMonitor;
// commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[JoinMap.IsOnline]);
// // Poewer Off
// trilist.SetSigTrueAction(JoinMap.PowerOff, () =>
// {
// InputNumber = 102;
// InputNumberFeedback.FireUpdate();
// displayDevice.PowerOff();
// });
// displayDevice.PowerIsOnFeedback.OutputChange += new EventHandler<FeedbackEventArgs>(PowerIsOnFeedback_OutputChange);
// displayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[JoinMap.PowerOff]);
// // Poewer On
// trilist.SetSigTrueAction(JoinMap.PowerOn, () =>
// {
// InputNumber = 0;
// InputNumberFeedback.FireUpdate();
// displayDevice.PowerOn();
// });
// displayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[JoinMap.PowerOn]);
// int count = 1;
// foreach (var input in displayDevice.InputPorts)
// {
// InputKeys.Add(input.Key.ToString());
// var tempKey = InputKeys.ElementAt(count - 1);
// trilist.SetSigTrueAction((ushort)(JoinMap.InputSelectOffset + count), () => { displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector); });
// trilist.StringInput[(ushort)(JoinMap.InputNamesOffset + count)].StringValue = input.Key.ToString();
// count++;
// }
// displayDevice.CurrentInputFeedback.OutputChange += new EventHandler<FeedbackEventArgs>(CurrentInputFeedback_OutputChange);
// trilist.SetUShortSigAction(JoinMap.InputSelect, (a) =>
// {
// if (a == 0)
// {
// displayDevice.PowerOff();
// InputNumber = 0;
// }
// else if (a > 0 && a < displayDevice.InputPorts.Count && a != InputNumber)
// {
// displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
// InputNumber = a;
// }
// else if (a == 102)
// {
// displayDevice.PowerToggle();
// }
// InputNumberFeedback.FireUpdate();
// });
// }
// static void CurrentInputFeedback_OutputChange(object sender, FeedbackEventArgs e)
// {
// Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", e.StringValue);
// }
// static void PowerIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
// {
// // Debug.Console(0, "PowerIsOnFeedback_OutputChange {0}", e.BoolValue);
// if (!e.BoolValue)
// {
// InputNumber = 102;
// InputNumberFeedback.FireUpdate();
// }
// else
// {
// InputNumber = 0;
// InputNumberFeedback.FireUpdate();
// }
// }
// }
// public class DisplayControllerJoinMap : JoinMapBase
// {
// public uint Name { get; set; }
// public uint InputNamesOffset { get; set; }
// public uint InputSelectOffset { get; set; }
// public uint IsOnline { get; set; }
// public uint PowerOff { get; set; }
// public uint InputSelect { get; set; }
// public uint PowerOn { get; set; }
// public uint SelectScene { get; set; }
// public uint LightingSceneOffset { get; set; }
// public uint ButtonVisibilityOffset { get; set; }
// public uint IntegrationIdSet { get; set; }
// public DisplayControllerJoinMap()
// {
// // Digital
// IsOnline = 50;
// PowerOff = 1;
// PowerOn = 2;
// InputSelect = 4;
// IntegrationIdSet = 1;
// LightingSceneOffset = 10;
// ButtonVisibilityOffset = 40;
// Name = 1;
// InputNamesOffset = 10;
// InputSelectOffset = 4;
// // Analog
// }
// public override void OffsetJoinNumbers(uint joinStart)
// {
// var joinOffset = joinStart - 1;
// IsOnline = IsOnline + joinOffset;
// PowerOff = PowerOff + joinOffset;
// PowerOn = PowerOn + joinOffset;
// SelectScene = SelectScene + joinOffset;
// LightingSceneOffset = LightingSceneOffset + joinOffset;
// ButtonVisibilityOffset = ButtonVisibilityOffset + joinOffset;
// Name = Name + joinOffset;
// InputNamesOffset = InputNamesOffset + joinOffset;
// InputSelectOffset = InputSelectOffset + joinOffset;
// }
// }
//}

View File

@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.DM;
namespace PepperDash.Essentials.Bridges
{
public static class DmChassisControllerApiExtentions
{
public static void LinkToApi(this DmChassisController dmChassis, BasicTriList trilist, uint joinStart, string joinMapKey)
{
var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DmChassisControllerJoinMap;
if (joinMap == null)
joinMap = new DmChassisControllerJoinMap();
joinMap.OffsetJoinNumbers(joinStart);
Debug.Console(1, dmChassis, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
dmChassis.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
// Link up outputs
for (uint i = 1; i <= dmChassis.Chassis.NumberOfOutputs - 1; i++)
{
var ioSlot = i;
// Control
trilist.SetUShortSigAction(joinMap.OutputVideo + ioSlot, new Action<ushort>(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)));
trilist.SetUShortSigAction(joinMap.OutputAudio + ioSlot, new Action<ushort>(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)));
if (dmChassis.TxDictionary.ContainsKey(ioSlot))
{
Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot);
var TxKey = dmChassis.TxDictionary[ioSlot];
var TxDevice = DeviceManager.GetDeviceForKey(TxKey) as DmTxControllerBase;
TxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]);
// TxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]);
// trilist.SetUShortSigAction((ApiMap.HdcpSupport[ioSlot]), u => TxDevice.SetHdcpSupportAll((ePdtHdcpSupport)(u)));
// TxDevice.HdcpSupportAllFeedback.LinkInputSig(trilist.UShortInput[joinMap. + ioSlot]);
// trilist.UShortInput[ApiMap.HdcpSupportCapability[ioSlot]].UShortValue = TxDevice.HdcpSupportCapability;
}
else
{
// dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[ApiMap.TxVideoSyncStatus[ioSlot]]);
}
if (dmChassis.RxDictionary.ContainsKey(ioSlot))
{
Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot);
var RxKey = dmChassis.RxDictionary[ioSlot];
var RxDevice = DeviceManager.GetDeviceForKey(RxKey) as DmRmcControllerBase;
RxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]);
}
// Feedback
dmChassis.VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo + ioSlot]);
dmChassis.AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio + ioSlot]);
dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]);
dmChassis.OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames + ioSlot]);
dmChassis.InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames + ioSlot]);
dmChassis.OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames + ioSlot]);
dmChassis.OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames + ioSlot]);
// dmChassis.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]);
// dmChassis.OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]);
}
}
public class DmChassisControllerJoinMap : JoinMapBase
{
public uint IsOnline { get; set; }
public uint OutputVideo { get; set; }
public uint OutputAudio { get; set; }
public uint VideoSyncStatus { get; set; }
public uint InputNames { get; set; }
public uint OutputNames { get; set; }
public uint OutputCurrentVideoInputNames { get; set; }
public uint OutputCurrentAudioInputNames { get; set; }
public uint InputCurrentResolution { get; set; }
public uint InputEndpointOnline { get; set; }
public uint OutputEndpointOnline { get; set; }
//public uint HdcpSupport { get; set; }
//public uint HdcpSupportCapability { get; set; }
public DmChassisControllerJoinMap()
{
IsOnline = 11;
OutputVideo = 100; //101-299
OutputAudio = 300; //301-499
VideoSyncStatus = 100; //101-299
InputNames = 100; //101-299
OutputNames = 300; //301-499
OutputCurrentVideoInputNames = 2000; //2001-2199
OutputCurrentAudioInputNames = 2200; //2201-2399
InputCurrentResolution = 2400; // 2401-2599
InputEndpointOnline = 500;
OutputEndpointOnline = 700;
//HdcpSupport = 1000; //1001-1199
//HdcpSupportCapability = 1200; //1201-1399
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
IsOnline = IsOnline + joinOffset;
OutputVideo = OutputVideo + joinOffset;
OutputAudio = OutputAudio + joinOffset;
VideoSyncStatus = VideoSyncStatus + joinOffset;
InputNames = InputNames + joinOffset;
OutputNames = OutputNames + joinOffset;
OutputCurrentVideoInputNames = OutputCurrentVideoInputNames + joinOffset;
OutputCurrentAudioInputNames = OutputCurrentAudioInputNames + joinOffset;
InputCurrentResolution = InputCurrentResolution + joinOffset;
InputEndpointOnline = InputEndpointOnline + joinOffset;
OutputEndpointOnline = OutputEndpointOnline + joinOffset;
//HdcpSupport = HdcpSupport + joinOffset;
//HdcpSupportCapability = HdcpSupportCapability + joinOffset;
}
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.DM;
namespace PepperDash.Essentials.Bridges
{
public static class DmRmcControllerApiExtensions
{
public static void LinkToApi(this DmRmcControllerBase rmc, BasicTriList trilist, uint joinStart, string joinMapKey)
{
var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DmRmcControllerJoinMap;
if (joinMap == null)
joinMap = new DmRmcControllerJoinMap();
joinMap.OffsetJoinNumbers(joinStart);
Debug.Console(1, rmc, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
rmc.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
if(rmc.VideoOutputResolutionFeedback != null)
rmc.VideoOutputResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentOutputResolution]);
if(rmc.EdidManufacturerFeedback != null)
rmc.EdidManufacturerFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidManufacturer]);
if(rmc.EdidNameFeedback != null)
rmc.EdidNameFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidName]);
if(rmc.EdidPreferredTimingFeedback != null)
rmc.EdidPreferredTimingFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidPrefferedTiming]);
if(rmc.EdidSerialNumberFeedback != null)
rmc.EdidSerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidSerialNumber]);
}
public class DmRmcControllerJoinMap : JoinMapBase
{
public uint IsOnline { get; set; }
public uint CurrentOutputResolution { get; set; }
public uint EdidManufacturer { get; set; }
public uint EdidName { get; set; }
public uint EdidPrefferedTiming { get; set; }
public uint EdidSerialNumber { get; set; }
public DmRmcControllerJoinMap()
{
// Digital
IsOnline = 1;
// Serial
CurrentOutputResolution = 1;
EdidManufacturer = 2;
EdidName = 3;
EdidPrefferedTiming = 4;
EdidSerialNumber = 5;
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
IsOnline = IsOnline + joinOffset;
CurrentOutputResolution = CurrentOutputResolution + joinOffset;
EdidManufacturer = EdidManufacturer + joinOffset;
EdidName = EdidName + joinOffset;
EdidPrefferedTiming = EdidPrefferedTiming + joinOffset;
EdidSerialNumber = EdidSerialNumber + joinOffset;
}
}
}
}

View File

@@ -0,0 +1,173 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.DM;
namespace PepperDash.Essentials.Bridges
{
public static class DmTxControllerApiExtensions
{
public static void LinkToApi(this DmTxControllerBase tx, BasicTriList trilist, uint joinStart, string joinMapKey)
{
var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DmTxControllerJoinMap;
if (joinMap == null)
joinMap = new DmTxControllerJoinMap();
joinMap.OffsetJoinNumbers(joinStart);
Debug.Console(1, tx, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
tx.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
tx.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus]);
tx.AnyVideoInput.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentInputResolution]);
//tx.HdcpSupportAllFeedback.LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportCapability]);
bool hdcpTypeSimple;
if (tx.Hardware is DmTx4kX02CBase || tx.Hardware is DmTx4kzX02CBase)
hdcpTypeSimple = false;
else
hdcpTypeSimple = true;
if (tx is ITxRouting)
{
var txR = tx as ITxRouting;
trilist.SetUShortSigAction(joinMap.VideoInput,
new Action<ushort>(i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Video)));
trilist.SetUShortSigAction(joinMap.AudioInput,
new Action<ushort>(i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Audio)));
txR.VideoSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoInput]);
txR.AudioSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.AudioInput]);
trilist.UShortInput[joinMap.HdcpSupportCapability].UShortValue = (ushort)tx.HdcpSupportCapability;
if(txR.InputPorts[DmPortName.HdmiIn] != null)
{
var inputPort = txR.InputPorts[DmPortName.HdmiIn];
if (tx.Feedbacks["HdmiInHdcpCapability"] != null)
(tx.Feedbacks["HdmiInHdcpCapability"] as IntFeedback).LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]);
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
{
var port = inputPort.Port as EndpointHdmiInput;
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState, trilist);
}
}
if (txR.InputPorts[DmPortName.HdmiIn1] != null)
{
var inputPort = txR.InputPorts[DmPortName.HdmiIn1];
if (tx.Feedbacks["HdmiIn1HdcpCapability"] != null)
(tx.Feedbacks["HdmiIn1HdcpCapability"] as IntFeedback).LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]);
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
{
var port = inputPort.Port as EndpointHdmiInput;
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState, trilist);
}
}
if (txR.InputPorts[DmPortName.HdmiIn2] != null)
{
var inputPort = txR.InputPorts[DmPortName.HdmiIn2];
if (tx.Feedbacks["HdmiIn2HdcpCapability"] != null)
(tx.Feedbacks["HdmiIn2HdcpCapability"] as IntFeedback).LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]);
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
{
var port = inputPort.Port as EndpointHdmiInput;
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port2HdcpState, trilist);
}
}
}
}
static void SetHdcpCapabilityAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist)
{
if (hdcpTypeSimple)
{
trilist.SetUShortSigAction(join,
new Action<ushort>(s =>
{
if (s == 0)
{
port.HdcpSupportOff();
}
else if (s > 0)
{
port.HdcpSupportOn();
}
}));
}
else
{
trilist.SetUShortSigAction(join,
new Action<ushort>(s =>
{
port.HdcpCapability = (eHdcpCapabilityType)s;
}));
}
}
public class DmTxControllerJoinMap : JoinMapBase
{
public uint IsOnline { get; set; }
public uint VideoSyncStatus { get; set; }
public uint CurrentInputResolution { get; set; }
public uint HdcpSupportCapability { get; set; }
public uint VideoInput { get; set; }
public uint AudioInput { get; set; }
public uint Port1HdcpState { get; set; }
public uint Port2HdcpState { get; set; }
public DmTxControllerJoinMap()
{
// Digital
IsOnline = 1;
VideoSyncStatus = 2;
// Serial
CurrentInputResolution = 1;
// Analog
VideoInput = 1;
AudioInput = 2;
HdcpSupportCapability = 3;
Port1HdcpState = 4;
Port2HdcpState = 5;
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
IsOnline = IsOnline + joinOffset;
VideoSyncStatus = VideoSyncStatus + joinOffset;
CurrentInputResolution = CurrentInputResolution + joinOffset;
VideoInput = VideoInput + joinOffset;
AudioInput = AudioInput + joinOffset;
HdcpSupportCapability = HdcpSupportCapability + joinOffset;
Port1HdcpState = Port1HdcpState + joinOffset;
Port2HdcpState = Port2HdcpState + joinOffset;
}
}
}
}

View File

@@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common;
namespace PepperDash.Essentials.Bridges
{
public static class SamsungDisplayControllerApiExtensions
{
public static void LinkToApi(this PepperDash.Essentials.Core.TwoWayDisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey)
{
var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DisplayControllerJoinMap;
if (joinMap == null)
{
joinMap = new DisplayControllerJoinMap();
}
joinMap.OffsetJoinNumbers(joinStart);
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to lighting Type {0}", displayDevice.GetType().Name.ToString());
var commMonitor = displayDevice as ICommunicationMonitor;
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
// Poewer Off
trilist.SetSigTrueAction(joinMap.PowerOff, () => displayDevice.PowerOff());
displayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff]);
// Poewer On
trilist.SetSigTrueAction(joinMap.PowerOn, () => displayDevice.PowerOn());
displayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn]);
// GenericLighitng Actions & FeedBack
// int sceneIndex = 1;
/*
foreach (var scene in displayDevice.LightingScenes)
{
var tempIndex = sceneIndex - 1;
//trilist.SetSigTrueAction((uint)(joinMap.LightingSceneOffset + sceneIndex), () => displayDevice.SelectScene(displayDevice.LightingScenes[tempIndex]));
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.LightingSceneOffset + sceneIndex)]);
trilist.StringInput[(uint)(joinMap.LightingSceneOffset + sceneIndex)].StringValue = scene.Name;
trilist.BooleanInput[(uint)(joinMap.ButtonVisibilityOffset + sceneIndex)].BoolValue = true;
sceneIndex++;
}
if (displayDevice.GetType().Name.ToString() == "LutronQuantumArea")
{
var lutronDevice = displayDevice as PepperDash.Essentials.Devices.Common.Environment.Lutron.LutronQuantumArea;
lutronDevice.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
trilist.SetStringSigAction(joinMap.IntegrationIdSet, s => lutronDevice.IntegrationId = s);
}
*/
//ApiEisc.Eisc.SetStringSigAction(ApiMap.integrationID, (s) => { lutronLights.IntegrationId = s; });
/*
var lutronLights = displayDevice as PepperDash.Essentials.Devices.Common.Environment.Lutron.LutronQuantumArea;
for (uint i = 1; i <= lightingBase.CircuitCount; i++)
{
var circuit = i;
lightingBase.CircuitNameFeedbacks[circuit - 1].LinkInputSig(trilist.StringInput[joinMap.CircuitNames + circuit]);
lightingBase.CircuitIsCritical[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitIsCritical + circuit]);
lightingBase.CircuitState[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitState + circuit]);
trilist.SetSigTrueAction(joinMap.CircuitCycle + circuit, () => lightingBase.CycleCircuit(circuit - 1));
trilist.SetSigTrueAction(joinMap.CircuitOnCmd + circuit, () => lightingBase.TurnOnCircuit(circuit - 1));
trilist.SetSigTrueAction(joinMap.CircuitOffCmd + circuit, () => lightingBase.TurnOffCircuit(circuit - 1));
}
*/
}
}
public class DisplayControllerJoinMap : JoinMapBase
{
public uint IsOnline { get; set; }
public uint PowerOff { get; set; }
public uint PowerOn { get; set; }
public uint SelectScene { get; set; }
public uint LightingSceneOffset { get; set; }
public uint ButtonVisibilityOffset { get; set; }
public uint IntegrationIdSet { get; set; }
public DisplayControllerJoinMap()
{
// Digital
IsOnline = 1;
PowerOff = 1;
PowerOn = 2;
SelectScene = 1;
IntegrationIdSet = 1;
LightingSceneOffset = 10;
ButtonVisibilityOffset = 40;
// Analog
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
IsOnline = IsOnline + joinOffset;
PowerOff = PowerOff + joinOffset;
PowerOn = PowerOn + joinOffset;
SelectScene = SelectScene + joinOffset;
LightingSceneOffset = LightingSceneOffset + joinOffset;
ButtonVisibilityOffset = ButtonVisibilityOffset + joinOffset;
}
}
}

View File

@@ -0,0 +1,144 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Core;
using PepperDash.Essentials.Core.Routing;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.EthernetCommunication;
using Crestron.SimplSharpPro.CrestronThread;
namespace PepperDash.Essentials {
public class EssentialCommConfig {
public string[] EiscApiIpids;
public EssentialCommCommConnectionConfigs[] CommConnections;
}
public class EssentialCommCommConnectionConfigs {
public uint joinNumber {get; set; }
public EssentialsControlPropertiesConfig control { get; set; }
}
public class EssentialCommsPort {
public IBasicCommunication Comm;
public IntFeedback StatusFeedback;
public BoolFeedback ConnectedFeedback;
public List<EssentialComApiMap> Outputs = new List<EssentialComApiMap>();
public String RxBuffer;
public EssentialCommsPort(EssentialsControlPropertiesConfig config, string keyPrefix) {
Comm = CommFactory.CreateCommForConfig(config, keyPrefix);
// var PortGather = new CommunicationGather(Comm, config.EndOfLineChar);
Comm.TextReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(Communication_TextReceived);
var socket = Comm as ISocketStatus;
StatusFeedback = new IntFeedback(() => { return (int)socket.ClientStatus; });
ConnectedFeedback = new BoolFeedback(() => { return Comm.IsConnected; });
if (socket != null) {
socket.ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(socket_ConnectionChange);
} else {
}
}
void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) {
StatusFeedback.FireUpdate();
ConnectedFeedback.FireUpdate();
if (e.Client.IsConnected) {
// Tasks on connect
} else {
// Cleanup items from this session
}
}
void Communication_TextReceived(object sender, GenericCommMethodReceiveTextArgs args) {
try {
foreach (var Output in Outputs) {
Output.Api.Eisc.StringInput[Output.Join].StringValue = args.Text;
}
}
catch (Exception) {
throw new FormatException(string.Format("ERROR:{0}"));
}
}
}
public class EssentialComm : Device {
public EssentialCommConfig Properties;
public CommunicationGather PortGather { get; private set; }
public List<BridgeApiEisc> Apis {get; set;}
public Dictionary<string, StringFeedback> CommFeedbacks {get; private set; }
public StatusMonitorBase CommunicationMonitor { get; private set; }
public Dictionary<uint, EssentialCommsPort> CommDictionary { get; private set; }
public EssentialComm(string key, string name, JToken properties) : base(key, name) {
Properties = JsonConvert.DeserializeObject<EssentialCommConfig>(properties.ToString());
CommFeedbacks = new Dictionary<string, StringFeedback>();
CommDictionary = new Dictionary<uint, EssentialCommsPort>();
Apis = new List<BridgeApiEisc>();
int commNumber = 1;
foreach (var commConfig in Properties.CommConnections) {
var commPort = new EssentialCommsPort(commConfig.control, string.Format("{0}-{1}", this.Key, commConfig.joinNumber));
CommDictionary.Add(commConfig.joinNumber, commPort);
commNumber++;
}
foreach (var Ipid in Properties.EiscApiIpids) {
var ApiEisc = new BridgeApiEisc(Ipid);
Apis.Add(ApiEisc);
foreach (var commConnection in CommDictionary) {
Debug.Console(2, "Joining Api{0} to comm {1}", Ipid, commConnection.Key);
var tempComm = commConnection.Value;
var tempJoin = (uint)commConnection.Key;
EssentialComApiMap ApiMap = new EssentialComApiMap(ApiEisc, (uint)tempJoin);
tempComm.Outputs.Add(ApiMap);
// Check for ApiMap Overide Values here
ApiEisc.Eisc.SetBoolSigAction(tempJoin, b => {if (b) { tempComm.Comm.Connect(); } else { tempComm.Comm.Disconnect(); }});
ApiEisc.Eisc.SetStringSigAction(tempJoin, s => tempComm.Comm.SendText(s));
tempComm.StatusFeedback.LinkInputSig(ApiEisc.Eisc.UShortInput[tempJoin]);
tempComm.ConnectedFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[tempJoin]);
}
ApiEisc.Eisc.Register();
}
}
public override bool CustomActivate()
{
try {
Debug.Console(2, "Name {0} Activated", this.Name);
return true;
}
catch (Exception e) {
Debug.Console(0, "Bridge {0}", e);
return false;
}
}
}
public class EssentialComApiMap {
public uint Join;
public BridgeApiEisc Api;
public uint connectJoin;
public EssentialComApiMap(BridgeApiEisc api, uint join) {
Join = join;
Api = api;
}
}
}

View File

@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.DM;
using PepperDash.Core;
using PepperDash.Essentials.Core.Routing;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.EthernetCommunication;
using Crestron.SimplSharpPro.DM;
namespace PepperDash.Essentials {
public class EssentialDM : PepperDash.Core.Device {
public EssentialDMProperties Properties;
public List<BridgeApiEisc> BridgeApiEiscs;
private PepperDash.Essentials.DM.DmChassisController DmSwitch;
private EssentialDMApiMap ApiMap = new EssentialDMApiMap();
public EssentialDM(string key, string name, JToken properties)
: base(key, name) {
Properties = JsonConvert.DeserializeObject<EssentialDMProperties>(properties.ToString());
}
public override bool CustomActivate() {
// Create EiscApis
try {
foreach (var device in DeviceManager.AllDevices) {
if (device.Key == this.Properties.connectionDeviceKey) {
Debug.Console(2, "deviceKey {0} Matches", device.Key);
DmSwitch = DeviceManager.GetDeviceForKey(device.Key) as PepperDash.Essentials.DM.DmChassisController;
}
else {
Debug.Console(2, "deviceKey {0} doesn't match", device.Key);
}
}
if (Properties.EiscApiIpids != null) {
foreach (string Ipid in Properties.EiscApiIpids) {
var ApiEisc = new BridgeApiEisc(Ipid);
for (uint x = 1; x <= DmSwitch.Chassis.NumberOfInputs;x++ ) {
uint tempX = x;
Debug.Console(2, "Creating EiscActions {0}", tempX);
ApiEisc.Eisc.SetUShortSigAction(ApiMap.OutputVideoRoutes[tempX], u => DmSwitch.ExecuteSwitch(u, tempX, eRoutingSignalType.Video));
ApiEisc.Eisc.SetUShortSigAction(ApiMap.OutputAudioRoutes[tempX], u => DmSwitch.ExecuteSwitch(u, tempX, eRoutingSignalType.Audio));
if (DmSwitch.TxDictionary.ContainsKey(tempX)) {
Debug.Console(2, "Creating Tx Feedbacks {0}", tempX);
var TxKey = DmSwitch.TxDictionary[tempX];
var TxDevice = DeviceManager.GetDeviceForKey(TxKey) as DmTxControllerBase;
TxDevice.IsOnline.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.TxOnlineStatus[tempX]]);
TxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.TxVideoSyncStatus[tempX]]);
ApiEisc.Eisc.SetUShortSigAction((ApiMap.HdcpSupport[tempX]), u => TxDevice.SetHdcpSupportAll((ePdtHdcpSupport)(u)));
TxDevice.HdcpSupportAllFeedback.LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.HdcpSupport[tempX]]);
ApiEisc.Eisc.UShortInput[ApiMap.HdcpSupportCapability[tempX]].UShortValue = TxDevice.HdcpSupportCapability;
}
else {
DmSwitch.VideoInputSyncFeedbacks[tempX].LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.TxVideoSyncStatus[tempX]]);
}
if (DmSwitch.RxDictionary.ContainsKey(tempX)) {
Debug.Console(2, "Creating Rx Feedbacks {0}", tempX);
var RxKey = DmSwitch.RxDictionary[tempX];
var RxDevice = DeviceManager.GetDeviceForKey(RxKey) as DmRmcControllerBase;
RxDevice.IsOnline.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.RxOnlineStatus[tempX]]);
}
// DmSwitch.InputEndpointOnlineFeedbacks[(ushort)tempOutputNum].LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.OutputVideoRoutes[tempOutputNum]]);
DmSwitch.VideoOutputFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.OutputVideoRoutes[tempX]]);
DmSwitch.AudioOutputFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.OutputAudioRoutes[tempX]]);
DmSwitch.InputNameFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.InputNames[tempX]]);
DmSwitch.OutputNameFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.OutputNames[tempX]]);
DmSwitch.OutputRouteNameFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.OutputRouteNames[tempX]]);
}
DmSwitch.IsOnline.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.ChassisOnline]);
ApiEisc.Eisc.Register();
}
}
Debug.Console(2, "Name {0} Activated", this.Name);
return true;
}
catch (Exception e) {
Debug.Console(2, "BRidge {0}", e);
return false;
}
}
}
public class EssentialDMProperties {
public string connectionDeviceKey;
public string[] EiscApiIpids;
}
public class EssentialDMApiMap {
public ushort ChassisOnline = 11;
public Dictionary<uint, ushort> OutputVideoRoutes;
public Dictionary<uint, ushort> OutputAudioRoutes;
public Dictionary<uint, ushort> TxOnlineStatus;
public Dictionary<uint, ushort> RxOnlineStatus;
public Dictionary<uint, ushort> TxVideoSyncStatus;
public Dictionary<uint, ushort> InputNames;
public Dictionary<uint, ushort> OutputNames;
public Dictionary<uint, ushort> OutputRouteNames;
public Dictionary<uint, ushort> HdcpSupport;
public Dictionary<uint, ushort> HdcpSupportCapability;
public EssentialDMApiMap() {
OutputVideoRoutes = new Dictionary<uint, ushort>();
OutputAudioRoutes = new Dictionary<uint, ushort>();
TxOnlineStatus = new Dictionary<uint, ushort>();
RxOnlineStatus = new Dictionary<uint, ushort>();
TxVideoSyncStatus = new Dictionary<uint, ushort>();
InputNames = new Dictionary<uint, ushort>();
OutputNames = new Dictionary<uint, ushort>();
OutputRouteNames = new Dictionary<uint, ushort>();
HdcpSupport = new Dictionary<uint, ushort>();
HdcpSupportCapability = new Dictionary<uint, ushort>();
for (uint x = 1; x <= 200; x++) {
// Debug.Console(0, "Init Value {0}", x);
uint tempNum = x;
HdcpSupportCapability[tempNum] = (ushort)(tempNum + 1200);
HdcpSupport[tempNum] = (ushort)(tempNum + 1000);
OutputVideoRoutes[tempNum] = (ushort)(tempNum + 100);
OutputAudioRoutes[tempNum] = (ushort)(tempNum + 300);
TxOnlineStatus[tempNum] = (ushort)(tempNum + 500);
RxOnlineStatus[tempNum] = (ushort)(tempNum + 700);
TxVideoSyncStatus[tempNum] = (ushort)(tempNum + 100);
InputNames[tempNum] = (ushort)(tempNum + 100);
OutputNames[tempNum] = (ushort)(tempNum + 300);
OutputRouteNames[tempNum] = (ushort)(tempNum + 2000);
}
}
}
}

View File

@@ -0,0 +1,217 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.DM;
using PepperDash.Core;
using PepperDash.Essentials.Core.Routing;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.EthernetCommunication;
using Crestron.SimplSharpPro.DM;
namespace PepperDash.Essentials {
public class EssentialDsp : PepperDash.Core.Device {
public EssentialDspProperties Properties;
public List<BridgeApiEisc> BridgeApiEiscs;
private PepperDash.Essentials.Devices.Common.DSP.QscDsp Dsp;
private EssentialDspApiMap ApiMap = new EssentialDspApiMap();
public EssentialDsp(string key, string name, JToken properties)
: base(key, name) {
Properties = JsonConvert.DeserializeObject<EssentialDspProperties>(properties.ToString());
}
public override bool CustomActivate() {
// Create EiscApis
try
{
ICommunicationMonitor comm = null;
foreach (var device in DeviceManager.AllDevices)
{
if (device.Key == this.Properties.connectionDeviceKey)
{
if (!(device is ICommunicationMonitor))
{
comm = device as ICommunicationMonitor;
}
Debug.Console(2, "deviceKey {0} Matches", device.Key);
Dsp = DeviceManager.GetDeviceForKey(device.Key) as PepperDash.Essentials.Devices.Common.DSP.QscDsp;
break;
}
else
{
Debug.Console(2, "deviceKey {0} doesn't match", device.Key);
}
}
if (Properties.EiscApiIpids != null && Dsp != null)
{
foreach (string Ipid in Properties.EiscApiIpids)
{
var ApiEisc = new BridgeApiEisc(Ipid);
Debug.Console(2, "Connecting EiscApi {0} to {1}", ApiEisc.Ipid, Dsp.Name);
ushort x = 1;
if (comm != null)
{
comm.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.Online]);
}
foreach (var channel in Dsp.LevelControlPoints)
{
//var QscChannel = channel.Value as PepperDash.Essentials.Devices.Common.DSP.QscDspLevelControl;
Debug.Console(2, "QscChannel {0} connect", x);
var genericChannel = channel.Value as IBasicVolumeWithFeedback;
if (channel.Value.Enabled)
{
ApiEisc.Eisc.StringInput[ApiMap.channelName[x]].StringValue = channel.Value.LevelCustomName;
ApiEisc.Eisc.UShortInput[ApiMap.channelType[x]].UShortValue = (ushort)channel.Value.Type;
genericChannel.MuteFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.channelMuteToggle[x]]);
genericChannel.VolumeLevelFeedback.LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.channelVolume[x]]);
ApiEisc.Eisc.SetSigTrueAction(ApiMap.channelMuteToggle[x], () => genericChannel.MuteToggle());
ApiEisc.Eisc.SetSigTrueAction(ApiMap.channelMuteOn[x], () => genericChannel.MuteOn());
ApiEisc.Eisc.SetSigTrueAction(ApiMap.channelMuteOff[x], () => genericChannel.MuteOff());
ApiEisc.Eisc.SetBoolSigAction(ApiMap.channelVolumeUp[x], b => genericChannel.VolumeUp(b));
ApiEisc.Eisc.SetBoolSigAction(ApiMap.channelVolumeDown[x], b => genericChannel.VolumeDown(b));
ApiEisc.Eisc.SetUShortSigAction(ApiMap.channelVolume[x], u => genericChannel.SetVolume(u));
ApiEisc.Eisc.SetStringSigAction(ApiMap.presetString, s => Dsp.RunPreset(s));
}
x++;
}
x = 1;
foreach (var preset in Dsp.PresetList)
{
ApiEisc.Eisc.StringInput[ApiMap.presets[x]].StringValue = preset.label;
ApiEisc.Eisc.SetSigTrueAction(ApiMap.presets[x], () => Dsp.RunPresetNumber(x));
x++;
}
foreach (var dialer in Dsp.Dialers)
{
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad0, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num0));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad1, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num1));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad2, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num2));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad3, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num3));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad4, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num4));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad5, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num5));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad6, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num6));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad7, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num7));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad8, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num8));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad9, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num9));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.KeypadStar, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Star));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.KeypadPound, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Pound));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.KeypadClear, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Clear));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.KeypadBackspace, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Backspace));
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Dial, () => dialer.Value.Dial());
ApiEisc.Eisc.SetSigTrueAction(ApiMap.DoNotDisturbToggle, () => dialer.Value.DoNotDisturbToggle());
ApiEisc.Eisc.SetSigTrueAction(ApiMap.DoNotDisturbOn, () => dialer.Value.DoNotDisturbOn());
ApiEisc.Eisc.SetSigTrueAction(ApiMap.DoNotDisturbOff, () => dialer.Value.DoNotDisturbOff());
ApiEisc.Eisc.SetSigTrueAction(ApiMap.AutoAnswerToggle, () => dialer.Value.AutoAnswerToggle());
ApiEisc.Eisc.SetSigTrueAction(ApiMap.AutoAnswerOn, () => dialer.Value.AutoAnswerOn());
ApiEisc.Eisc.SetSigTrueAction(ApiMap.AutoAnswerOff, () => dialer.Value.AutoAnswerOff());
dialer.Value.DoNotDisturbFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.DoNotDisturbToggle]);
dialer.Value.DoNotDisturbFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.DoNotDisturbOn]);
dialer.Value.DoNotDisturbFeedback.LinkComplementInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.DoNotDisturbOff]);
dialer.Value.AutoAnswerFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.AutoAnswerToggle]);
dialer.Value.AutoAnswerFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.AutoAnswerOn]);
dialer.Value.AutoAnswerFeedback.LinkComplementInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.AutoAnswerOff]);
dialer.Value.OffHookFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.Dial]);
dialer.Value.DialStringFeedback.LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.DialString]);
}
}
}
Debug.Console(2, "Name {0} Activated", this.Name);
return true;
}
catch (Exception e) {
Debug.Console(0, "Bridge {0}", e);
return false;
}
}
}
public class EssentialDspProperties {
public string connectionDeviceKey;
public string[] EiscApiIpids;
}
public class EssentialDspApiMap {
public ushort Online = 1;
public ushort presetString = 2000;
public Dictionary<uint, ushort> channelMuteToggle;
public Dictionary<uint, ushort> channelMuteOn;
public Dictionary<uint, ushort> channelMuteOff;
public Dictionary<uint, ushort> channelVolume;
public Dictionary<uint, ushort> channelType;
public Dictionary<uint, ushort> channelName;
public Dictionary<uint, ushort> channelVolumeUp;
public Dictionary<uint, ushort> channelVolumeDown;
public Dictionary<uint, ushort> presets;
public ushort DialString = 3100;
public ushort Keypad0 = 3110;
public ushort Keypad1 = 3111;
public ushort Keypad2 = 3112;
public ushort Keypad3 = 3113;
public ushort Keypad4 = 3114;
public ushort Keypad5 = 3115;
public ushort Keypad6 = 3116;
public ushort Keypad7 = 3117;
public ushort Keypad8 = 3118;
public ushort Keypad9 = 3119;
public ushort KeypadStar = 3120;
public ushort KeypadPound = 3121;
public ushort KeypadClear = 3122;
public ushort KeypadBackspace = 3123;
public ushort Dial = 3124;
public ushort DoNotDisturbToggle = 3132;
public ushort DoNotDisturbOn = 3133;
public ushort DoNotDisturbOff = 3134;
public ushort AutoAnswerToggle = 3127;
public ushort AutoAnswerOn = 3125;
public ushort AutoAnswerOff = 3126;
public EssentialDspApiMap() {
channelMuteToggle = new Dictionary<uint, ushort>();
channelMuteOn = new Dictionary<uint, ushort>();
channelMuteOff = new Dictionary<uint, ushort>();
channelVolume = new Dictionary<uint, ushort>();
channelName = new Dictionary<uint, ushort>();
channelType = new Dictionary<uint, ushort>();
presets = new Dictionary<uint, ushort>();
channelVolumeUp = new Dictionary<uint, ushort>();
channelVolumeDown = new Dictionary<uint, ushort>();
for (uint x = 1; x <= 100; x++) {
uint tempNum = x;
presets[tempNum] = (ushort)(tempNum + 100);
channelMuteToggle[tempNum] = (ushort)(tempNum + 400);
channelMuteOn[tempNum] = (ushort)(tempNum + 600);
channelMuteOff[tempNum] = (ushort)(tempNum + 800);
channelVolume[tempNum] = (ushort)(tempNum + 200);
channelName[tempNum] = (ushort)(tempNum + 200);
channelType[tempNum] = (ushort)(tempNum + 400);
channelVolumeUp[tempNum] = (ushort)(tempNum + 1000);
channelVolumeDown[tempNum] = (ushort)(tempNum + 1200);
}
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.DM;
using PepperDash.Core;
using PepperDash.Essentials.Core.Routing;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.EthernetCommunication;
using Crestron.SimplSharpPro.DM;
namespace PepperDash.Essentials
{
public class EssentialsTVOne : PepperDash.Core.Device
{
public EssentialTVOneProperties Properties;
public List<BridgeApiEisc> BridgeApiEiscs;
private PepperDash.Essentials.Devices.Common.TVOneCorio TVOneCorio;
private EssentialsTVOneApiMap ApiMap = new EssentialsTVOneApiMap();
public EssentialsTVOne(string key, string name, JToken properties)
: base(key, name)
{
Properties = JsonConvert.DeserializeObject<EssentialTVOneProperties>(properties.ToString());
}
public override bool CustomActivate() {
// Create EiscApis
try
{
foreach (var device in DeviceManager.AllDevices)
{
if (device.Key == this.Properties.connectionDeviceKey)
{
Debug.Console(2, "deviceKey {0} Matches", device.Key);
TVOneCorio = DeviceManager.GetDeviceForKey(device.Key) as PepperDash.Essentials.Devices.Common.TVOneCorio;
break;
}
else
{
Debug.Console(2, "deviceKey {0} doesn't match", device.Key);
}
}
if (Properties.EiscApiIpids != null && TVOneCorio != null)
{
foreach (string Ipid in Properties.EiscApiIpids)
{
var ApiEisc = new BridgeApiEisc(Ipid);
Debug.Console(2, "Connecting EiscApi {0} to {1}", ApiEisc.Ipid, TVOneCorio.Name);
ushort x = 1;
TVOneCorio.OnlineFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.Online]);
ApiEisc.Eisc.SetUShortSigAction(ApiMap.CallPreset, u => TVOneCorio.CallPreset(u));
TVOneCorio.PresetFeedback.LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.PresetFeedback]);
}
}
Debug.Console(2, "Name {0} Activated", this.Name);
return true;
}
catch (Exception e) {
Debug.Console(0, "Bridge {0}", e);
return false;
}
}
}
public class EssentialTVOneProperties
{
public string connectionDeviceKey;
public string[] EiscApiIpids;
}
public class EssentialsTVOneApiMap
{
public ushort CallPreset = 1;
public ushort PresetFeedback = 1;
public ushort Online = 1;
public EssentialsTVOneApiMap()
{
}
}
}

View File

@@ -0,0 +1,103 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharpPro.DeviceSupport;
//using PepperDash.Core;
//using PepperDash.Essentials.Core;
//using PepperDash.Essentials.Devices.Common;
//namespace PepperDash.Essentials.Bridges
//{
// public static class GenericLightingApiExtensions
// {
// public static void LinkToApi(this PepperDash.Essentials.Core.Lighting.LightingBase lightingDevice, BasicTriList trilist, uint joinStart, string joinMapKey)
// {
// var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as GenericLightingJoinMap;
// if (joinMap == null)
// joinMap = new GenericLightingJoinMap();
// joinMap.OffsetJoinNumbers(joinStart);
// Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Debug.Console(0, "Linking to lighting Type {0}", lightingDevice.GetType().Name.ToString());
// // GenericLighitng Actions & FeedBack
// trilist.SetUShortSigAction(joinMap.SelectScene, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
// int sceneIndex = 1;
// foreach (var scene in lightingDevice.LightingScenes)
// {
// var tempIndex = sceneIndex - 1;
// trilist.SetSigTrueAction((uint)(joinMap.LightingSceneOffset + sceneIndex), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[tempIndex]));
// scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.LightingSceneOffset + sceneIndex)]);
// trilist.StringInput[(uint)(joinMap.LightingSceneOffset + sceneIndex)].StringValue = scene.Name;
// trilist.BooleanInput[(uint)(joinMap.ButtonVisibilityOffset + sceneIndex)].BoolValue = true;
// sceneIndex++;
// }
// if (lightingDevice.GetType().Name.ToString() == "LutronQuantumArea")
// {
// var lutronDevice = lightingDevice as PepperDash.Essentials.Devices.Common.Environment.Lutron.LutronQuantumArea;
// lutronDevice.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
// trilist.SetStringSigAction(joinMap.IntegrationIdSet, s => lutronDevice.IntegrationId = s);
// }
// //ApiEisc.Eisc.SetStringSigAction(ApiMap.integrationID, (s) => { lutronLights.IntegrationId = s; });
// /*
// var lutronLights = lightingDevice as PepperDash.Essentials.Devices.Common.Environment.Lutron.LutronQuantumArea;
// for (uint i = 1; i <= lightingBase.CircuitCount; i++)
// {
// var circuit = i;
// lightingBase.CircuitNameFeedbacks[circuit - 1].LinkInputSig(trilist.StringInput[joinMap.CircuitNames + circuit]);
// lightingBase.CircuitIsCritical[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitIsCritical + circuit]);
// lightingBase.CircuitState[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitState + circuit]);
// trilist.SetSigTrueAction(joinMap.CircuitCycle + circuit, () => lightingBase.CycleCircuit(circuit - 1));
// trilist.SetSigTrueAction(joinMap.CircuitOnCmd + circuit, () => lightingBase.TurnOnCircuit(circuit - 1));
// trilist.SetSigTrueAction(joinMap.CircuitOffCmd + circuit, () => lightingBase.TurnOffCircuit(circuit - 1));
// }
// */
// }
// }
// public class GenericLightingJoinMap : JoinMapBase
// {
// public uint IsOnline { get; set; }
// public uint SelectScene { get; set; }
// public uint LightingSceneOffset { get; set; }
// public uint ButtonVisibilityOffset { get; set; }
// public uint IntegrationIdSet { get; set; }
// public GenericLightingJoinMap()
// {
// // Digital
// IsOnline = 1;
// SelectScene = 1;
// IntegrationIdSet = 1;
// LightingSceneOffset = 10;
// ButtonVisibilityOffset = 40;
// // Analog
// }
// public override void OffsetJoinNumbers(uint joinStart)
// {
// var joinOffset = joinStart - 1;
// IsOnline = IsOnline + joinOffset;
// SelectScene = SelectScene + joinOffset;
// LightingSceneOffset = LightingSceneOffset + joinOffset;
// ButtonVisibilityOffset = ButtonVisibilityOffset + joinOffset;
// }
// }
//}

View File

@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.CrestronIO;
namespace PepperDash.Essentials.Bridges
{
public static class GenericRelayDeviceApiExtensions
{
public static void LinkToApi(this GenericRelayDevice relay, BasicTriList trilist, uint joinStart, string joinMapKey)
{
var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as GenericRelayControllerJoinMap;
if (joinMap == null)
joinMap = new GenericRelayControllerJoinMap();
joinMap.OffsetJoinNumbers(joinStart);
if (relay.RelayOutput == null)
{
Debug.Console(1, relay, "Unable to link device '{0}'. Relay is null", relay.Key);
return;
}
Debug.Console(1, relay, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
trilist.SetBoolSigAction(joinMap.Relay, new Action<bool>(b =>
{
if (b)
relay.CloseRelay();
else
relay.OpenRelay();
}));
// feedback for relay state
relay.OutputIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Relay]);
}
}
public class GenericRelayControllerJoinMap : JoinMapBase
{
//Digital
public uint Relay { get; set; }
public GenericRelayControllerJoinMap()
{
Relay = 1;
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
Relay = Relay + joinOffset;
}
}
}

View File

@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Bridges
{
public static class IBasicCommunicationApiExtensions
{
public static void LinkToApi(this GenericComm comm, BasicTriList trilist, uint joinStart, string joinMapKey)
{
var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as IBasicCommunicationJoinMap;
if (joinMap == null)
joinMap = new IBasicCommunicationJoinMap();
joinMap.OffsetJoinNumbers(joinStart);
if (comm.CommPort == null)
{
Debug.Console(1, comm, "Unable to link device '{0}'. CommPort is null", comm.Key);
return;
}
Debug.Console(1, comm, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// this is a permanent event handler. This cannot be -= from event
comm.CommPort.TextReceived += (s, a) =>
{
Debug.Console(2, comm, "RX: {0}", a.Text);
trilist.SetString(joinMap.TextReceived, a.Text);
};
trilist.SetStringSigAction(joinMap.SendText, new Action<string>(s => comm.CommPort.SendText(s)));
trilist.SetStringSigAction(joinMap.SetPortConfig + 1, new Action<string>(s => comm.SetPortConfig(s)));
var sComm = comm.CommPort as ISocketStatus;
if (sComm != null)
{
sComm.ConnectionChange += (s, a) =>
{
trilist.SetUshort(joinMap.Status, (ushort)(a.Client.ClientStatus));
trilist.SetBool(joinMap.Connected, a.Client.ClientStatus ==
Crestron.SimplSharp.CrestronSockets.SocketStatus.SOCKET_STATUS_CONNECTED);
};
trilist.SetBoolSigAction(joinMap.Connect, new Action<bool>(b =>
{
if (b)
{
sComm.Connect();
}
else
{
sComm.Disconnect();
}
}));
}
}
public class IBasicCommunicationJoinMap : JoinMapBase
{
//Digital
public uint Connect { get; set; }
public uint Connected { get; set; }
//Analog
public uint Status { get; set; }
// Serial
public uint TextReceived { get; set; }
public uint SendText { get; set; }
public uint SetPortConfig { get; set; }
public IBasicCommunicationJoinMap()
{
TextReceived = 1;
SendText = 1;
SetPortConfig = 2;
Connect = 1;
Connected = 1;
Status = 1;
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
TextReceived = TextReceived + joinOffset;
SendText = SendText + joinOffset;
SetPortConfig = SetPortConfig + joinOffset;
Connect = Connect + joinOffset;
Connected = Connected + joinOffset;
Status = Status + joinOffset;
}
}
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.CrestronIO;
namespace PepperDash.Essentials.Bridges
{
public static class IDigitalInputApiExtenstions
{
public static void LinkToApi(this IDigitalInput input, BasicTriList trilist, uint joinStart, string joinMapKey)
{
var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as IDigitalInputApiJoinMap;
if (joinMap == null)
joinMap = new IDigitalInputApiJoinMap();
joinMap.OffsetJoinNumbers(joinStart);
try
{
Debug.Console(1, input as Device, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state
input.InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState]);
}
catch (Exception e)
{
Debug.Console(1, input as Device, "Unable to link device '{0}'. Input is null", (input as Device).Key);
Debug.Console(1, input as Device, "Error: {0}", e);
return;
}
}
}
public class IDigitalInputApiJoinMap : JoinMapBase
{
//Digital
public uint InputState { get; set; }
public IDigitalInputApiJoinMap()
{
InputState = 1;
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
InputState = InputState + joinOffset;
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Bridges
{
public static class JoinMapHelper
{
/// <summary>
/// Attempts to get the join map from config
/// </summary>
/// <param name="joinMapKey"></param>
/// <returns></returns>
public static JoinMapBase GetJoinMapForDevice(string joinMapKey)
{
if (!string.IsNullOrEmpty(joinMapKey))
return null;
// FUTURE TODO: Get the join map from the ConfigReader.ConfigObject
return null;
}
}
public abstract class JoinMapBase
{
/// <summary>
/// Modifies all the join numbers by adding the offset. This should never be called twice
/// </summary>
/// <param name="joinStart"></param>
public abstract void OffsetJoinNumbers(uint joinStart);
}
}

View File

@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.Diagnostics;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Monitoring;
namespace PepperDash.Essentials.Bridges
{
public static class SystemMonitorBridge
{
public static void LinkToApi(this SystemMonitorController systemMonitorController, BasicTriList trilist, uint joinStart, string joinMapKey)
{
var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as SystemMonitorJoinMap;
if (joinMap == null)
joinMap = new SystemMonitorJoinMap();
joinMap.OffsetJoinNumbers(joinStart);
//Debug.Console(1, systemMonitorController, "Linking API starting at join: {0}", joinStart);
systemMonitorController.TimeZoneFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeZone]);
//trilist.SetUShortSigAction(joinMap.TimeZone, new Action<ushort>(u => systemMonitorController.SetTimeZone(u)));
systemMonitorController.TimeZoneTextFeedback.LinkInputSig(trilist.StringInput[joinMap.TimeZoneName]);
systemMonitorController.IOControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.IOControllerVersion]);
systemMonitorController.SnmpVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.SnmpAppVersion]);
systemMonitorController.BACnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]);
systemMonitorController.ControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.ControllerVersion]);
// iterate the program status feedback collection and map all the joins
var programSlotJoinStart = joinMap.ProgramStartJoin;
foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection)
{
// TODO: link feedbacks for each program slot
var programNumber = p.Value.Program.Number;
//Debug.Console(1, systemMonitorController, "Linking API for Program Slot: {0} starting at join: {1}", programNumber, programSlotJoinStart);
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart, new Action<bool>
(b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start));
p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart]);
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop, new Action<bool>
(b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop));
p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop]);
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister, new Action<bool>
(b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register));
p.Value.ProgramRegisteredFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]);
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister, new Action<bool>
(b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister));
p.Value.ProgramUnregisteredFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]);
programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin;
}
}
}
public class SystemMonitorJoinMap : JoinMapBase
{
/// <summary>
/// Offset to indicate where the range of iterated program joins will start
/// </summary>
public uint ProgramStartJoin { get; set; }
/// <summary>
/// Offset between each program join set
/// </summary>
public uint ProgramOffsetJoin { get; set; }
//Digital
public uint ProgramStart { get; set; }
public uint ProgramStop { get; set; }
public uint ProgramRegister { get; set; }
public uint ProgramUnregister { get; set; }
//Analog
public uint TimeZone { get; set; }
//Serial
public uint TimeZoneName { get; set; }
public uint IOControllerVersion { get; set; }
public uint SnmpAppVersion { get; set; }
public uint BACnetAppVersion { get; set; }
public uint ControllerVersion { get; set; }
public uint ProgramName { get; set; }
public uint ProgramCompiledTime { get; set; }
public uint ProgramCrestronDatabaseVersion { get; set; }
public uint ProgramEnvironmentVersion { get; set; }
public uint AggregatedProgramInfo { get; set; }
public SystemMonitorJoinMap()
{
TimeZone = 1;
TimeZoneName = 1;
IOControllerVersion = 2;
SnmpAppVersion = 3;
BACnetAppVersion = 4;
ControllerVersion = 5;
ProgramStartJoin = 10;
ProgramOffsetJoin = 5;
// Offset in groups of 5 joins
ProgramStart = 1;
ProgramStop = 2;
ProgramRegister = 3;
ProgramUnregister = 4;
ProgramName = 1;
ProgramCompiledTime = 2;
ProgramCrestronDatabaseVersion = 3;
ProgramEnvironmentVersion = 4;
AggregatedProgramInfo = 5;
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
TimeZone = TimeZone + joinOffset;
TimeZoneName = TimeZoneName + joinOffset;
IOControllerVersion = IOControllerVersion + joinOffset;
SnmpAppVersion = SnmpAppVersion + joinOffset;
BACnetAppVersion = BACnetAppVersion + joinOffset;
ControllerVersion = ControllerVersion + joinOffset;
// Sets the initial join value where the iterated program joins will begin
ProgramStartJoin = ProgramStartJoin + joinOffset;
}
}
}

View File

@@ -80,6 +80,16 @@ namespace PepperDash.Essentials
var dm = new DmMd8x8(ipId, Global.ControlSystem);
//dev = new DmChassisController(devKey, devName, dm);
}
else if (devType.Equals("dmmd16x16", StringComparison.OrdinalIgnoreCase))
{
var dm = new DmMd16x16(ipId, Global.ControlSystem);
//dev = new DmChassisController(devKey, devName, dm);
}
else if (devType.Equals("dmmd32x32", StringComparison.OrdinalIgnoreCase))
{
var dm = new DmMd32x32(ipId, Global.ControlSystem);
//dev = new DmChassisController(devKey, devName, dm);
}
}
catch (Exception e)
{

View File

@@ -4,6 +4,8 @@ using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.CrestronThread;
using Crestron.SimplSharpPro.Diagnostics;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
@@ -38,6 +40,10 @@ namespace PepperDash.Essentials
// ConsoleAccessLevelEnum.AccessOperator);
// CrestronConsole.AddNewConsoleCommand(S => { ConfigWriter.WriteConfigFile(null); }, "writeconfig", "writes the current config to a file", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s);
}, "appdebugmessage", "Writes message to log", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
@@ -65,7 +71,7 @@ namespace PepperDash.Essentials
}
/// <summary>
/// Determines if the program is running on a processor (appliance) or server (XiO Edge).
/// Determines if the program is running on a processor (appliance) or server (VC-4).
///
/// Sets Global.FilePathPrefix based on platform
/// </summary>
@@ -85,20 +91,40 @@ namespace PepperDash.Essentials
directoryPrefix = Crestron.SimplSharp.CrestronIO.Directory.GetApplicationRootDirectory();
//directoryPrefix = "";
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server)
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows OS
{
filePathPrefix = directoryPrefix + dirSeparator + "NVRAM"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", versionString);
}
else
{
filePathPrefix = directoryPrefix + dirSeparator + "User" + dirSeparator;
// 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;
}
}
else // Handles Linux OS (Virtual Control)
{
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);
@@ -141,16 +167,22 @@ namespace PepperDash.Essentials
"------------------------------------------------\r" +
"------------------------------------------------");
}
}
catch (Exception e)
{
Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e);
}
// Notify the OS that the program intitialization has completed
SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
}
/// <summary>
/// Verifies filesystem is set up. IR, SGD, and program1 folders
/// Verifies filesystem is set up. IR, SGD, and programX folders
/// </summary>
bool SetupFilesystem()
{
@@ -203,16 +235,39 @@ namespace PepperDash.Essentials
LoadLogoServer();
DeviceManager.ActivateAll();
LinkSystemMonitorToAppServer();
}
void LinkSystemMonitorToAppServer()
{
var sysMon = DeviceManager.GetDeviceForKey("systemMonitor") as PepperDash.Essentials.Core.Monitoring.SystemMonitorController;
var appServer = DeviceManager.GetDeviceForKey("appServer") as CotijaSystemController;
if (sysMon != null && appServer != null)
{
var key = sysMon.Key + "-" + appServer.Key;
var messenger = new PepperDash.Essentials.AppServer.Messengers.SystemMonitorMessenger
(key, sysMon, "/device/systemMonitor");
messenger.RegisterWithAppServer(appServer);
DeviceManager.AddDevice(messenger);
}
}
/// <summary>
/// Reads all devices from config and adds them to DeviceManager
/// </summary>
public void LoadDevices()
{
// Build the processor wrapper class
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));
// Build the processor wrapper class
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));
// Add global System Monitor device
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor"));
foreach (var devConf in ConfigReader.ConfigObject.Devices)
{
@@ -231,17 +286,23 @@ namespace PepperDash.Essentials
continue;
}
// Try local factory first
// Try local factories first
var newDev = DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = BridgeFactory.GetDevice(devConf);
// Then associated library factories
if (newDev == null)
newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.BridgeFactory.GetDevice(devConf);
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
@@ -256,6 +317,7 @@ namespace PepperDash.Essentials
}
/// <summary>
/// Helper method to load tie lines. This should run after devices have loaded
/// </summary>

View File

@@ -1,367 +0,0 @@
using System;
using System.Linq;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.CrestronThread;
using PepperDash.Core;
using PepperDash.Core.PortalSync;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
using PepperDash.Essentials.Room.Cotija;
namespace PepperDash.Essentials
{
public class ControlSystem : CrestronControlSystem
{
PepperDashPortalSyncClient PortalSync;
HttpLogoServer LogoServer;
public ControlSystem()
: base()
{
Thread.MaxNumberOfUserThreads = 400;
Global.ControlSystem = this;
DeviceManager.Initialize(this);
}
/// <summary>
/// Git 'er goin'
/// </summary>
public override void InitializeSystem()
{
<<<<<<< HEAD
DeterminePlatform();
//CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
// ConsoleAccessLevelEnum.AccessOperator);
=======
CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
ConsoleAccessLevelEnum.AccessOperator);
>>>>>>> 600b9f11ff1bbc186f7c2a2945955731b3523b3c
CrestronConsole.AddNewConsoleCommand(s =>
{
foreach (var tl in TieLineCollection.Default)
CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
},
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse
("Current running configuration. This is the merged system and template configuration");
CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject
(ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented));
}, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
"System URL: {0}\r" +
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
//GoWithLoad();
}
/// <summary>
/// Determines if the program is running on a processor (appliance) or server (XiO Edge).
///
/// Sets Global.FilePathPrefix based on platform
/// </summary>
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();
#warning ^ For use with beta Include4.dat for XiO Edge
directoryPrefix = "";
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server)
{
filePathPrefix = directoryPrefix + dirSeparator + "NVRAM"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", versionString);
}
else
{
filePathPrefix = directoryPrefix + dirSeparator + "User" + dirSeparator;
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on XiO Edge Server", versionString);
}
Global.SetFilePathPrefix(filePathPrefix);
}
/// <summary>
/// Do it, yo
/// </summary>
public void GoWithLoad()
{
try
{
CrestronConsole.AddNewConsoleCommand(EnablePortalSync, "portalsync", "Loads Portal Sync",
ConsoleAccessLevelEnum.AccessOperator);
//PortalSync = new PepperDashPortalSyncClient();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration");
var filesReady = SetupFilesystem();
if (filesReady)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Folder structure verified. Loading config...");
if (!ConfigReader.LoadConfig2())
return;
Load();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Essentials load complete\r" +
"-------------------------------------------------------------");
}
else
{
Debug.Console(0,
"------------------------------------------------\r" +
"------------------------------------------------\r" +
"------------------------------------------------\r" +
"Essentials file structure setup completed.\r" +
"Please load config, sgd and ir files and\r" +
"restart program.\r" +
"------------------------------------------------\r" +
"------------------------------------------------\r" +
"------------------------------------------------");
}
}
catch (Exception e)
{
Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e);
}
}
/// <summary>
/// Verifies filesystem is set up. IR, SGD, and program1 folders
/// </summary>
bool SetupFilesystem()
{
Debug.Console(0, "Verifying and/or creating folder structure");
var configDir = Global.FilePathPrefix;
var configExists = Directory.Exists(configDir);
if (!configExists)
Directory.Create(configDir);
var irDir = Global.FilePathPrefix + "ir";
if (!Directory.Exists(irDir))
Directory.Create(irDir);
var sgdDir = Global.FilePathPrefix + "sgd";
if (!Directory.Exists(sgdDir))
Directory.Create(sgdDir);
return configExists;
}
public void EnablePortalSync(string s)
{
if (s.ToLower() == "enable")
{
CrestronConsole.ConsoleCommandResponse("Portal Sync features enabled");
PortalSync = new PepperDashPortalSyncClient();
}
}
public void TearDown()
{
Debug.Console(0, "Tearing down existing system");
DeviceManager.DeactivateAll();
TieLineCollection.Default.Clear();
foreach (var key in DeviceManager.GetDevices())
DeviceManager.RemoveDevice(key);
Debug.Console(0, "Tear down COMPLETE");
}
/// <summary>
///
/// </summary>
void Load()
{
LoadDevices();
LoadTieLines();
LoadRooms();
LoadLogoServer();
DeviceManager.ActivateAll();
}
/// <summary>
/// Reads all devices from config and adds them to DeviceManager
/// </summary>
public void LoadDevices()
{
foreach (var devConf in ConfigReader.ConfigObject.Devices)
{
try
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Creating device '{0}'", devConf.Key);
// Skip this to prevent unnecessary warnings
if (devConf.Key == "processor")
continue;
// Try local factory first
var newDev = DeviceFactory.GetDevice(devConf);
// Then associated library factories
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
}
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded.");
}
/// <summary>
/// Helper method to load tie lines. This should run after devices have loaded
/// </summary>
public void LoadTieLines()
{
// In the future, we can't necessarily just clear here because devices
// might be making their own internal sources/tie lines
var tlc = TieLineCollection.Default;
//tlc.Clear();
if (ConfigReader.ConfigObject.TieLines == null)
{
return;
}
foreach (var tieLineConfig in ConfigReader.ConfigObject.TieLines)
{
var newTL = tieLineConfig.GetTieLine();
if (newTL != null)
tlc.Add(newTL);
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Tie Lines Loaded.");
}
/// <summary>
/// Reads all rooms from config and adds them to DeviceManager
/// </summary>
public void LoadRooms()
{
if (ConfigReader.ConfigObject.Rooms == null)
{
Debug.Console(0, Debug.ErrorLogLevel.Warning, "WARNING: Configuration contains no rooms");
return;
}
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
{
var room = roomConfig.GetRoomObject();
if (room != null)
{
if (room is EssentialsHuddleSpaceRoom)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Cotija Bridge...");
// Cotija bridge
var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(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...");
}
else if (room is EssentialsHuddleVtc1Room)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsHuddleSpaceRoom, attempting to add to DeviceManager w/o Fusion");
DeviceManager.AddDevice(room);
}
}
else
Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key);
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded.");
}
/// <summary>
/// Helps add the post activation steps that link bridges to main controller
/// </summary>
/// <param name="bridge"></param>
void AddBridgePostActivationHelper(CotijaBridgeBase bridge)
{
bridge.AddPostActivationAction(() =>
{
var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as CotijaSystemController;
if (parent == null)
{
Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present");
}
Debug.Console(0, bridge, "Linking to parent controller");
bridge.AddParent(parent);
parent.AddBridge(bridge);
});
}
/// <summary>
/// Fires up a logo server if not already running
/// </summary>
void LoadLogoServer()
{
try
{
LogoServer = new HttpLogoServer(8080, Global.FilePathPrefix + "html" + Global.DirectorySeparator + "logo");
}
catch (Exception)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "NOTICE: Logo server cannot be started. Likely already running in another program");
}
}
}
}

View File

@@ -1,348 +1,348 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.Fusion;
using PepperDash.Core;
using PepperDash.Essentials;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.Devices.Common.Occupancy;
namespace PepperDash.Essentials.Fusion
{
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
{
BooleanSigData CodecIsInCall;
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
: base(room, ipId)
{
}
/// <summary>
/// Called in base class constructor before RVI and GUID files are built
/// </summary>
protected override void ExecuteCustomSteps()
{
SetUpCodec();
}
/// <summary>
/// Creates a static asset for the codec and maps the joins to the main room symbol
/// </summary>
void SetUpCodec()
{
try
{
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
if (codec == null)
{
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
return;
}
codec.UsageTracker = new UsageTracking(codec);
codec.UsageTracker.UsageIsTracked = true;
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
var codecPowerOnAction = new Action<bool>(b => { if (!b) codec.StandbyDeactivate(); });
var codecPowerOffAction = new Action<bool>(b => { if (!b) codec.StandbyActivate(); });
// Map FusionRoom Attributes:
// Codec volume
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
codecVolume.OutputSig.UserObject = new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
// In Call Status
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
codec.CallStatusChange += new EventHandler<PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
// Online status
if (codec is ICommunicationMonitor)
{
var c = codec as ICommunicationMonitor;
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
c.CommunicationMonitor.StatusChange += (o, a) =>
{
codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
};
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1");
}
// Codec IP Address
bool codecHasIpInfo = false;
var codecComm = codec.Communication;
string codecIpAddress = string.Empty;
int codecIpPort = 0;
StringSigData codecIpAddressSig;
StringSigData codecIpPortSig;
if(codecComm is GenericSshClient)
{
codecIpAddress = (codecComm as GenericSshClient).Hostname;
codecIpPort = (codecComm as GenericSshClient).Port;
codecHasIpInfo = true;
}
else if (codecComm is GenericTcpIpClient)
{
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
codecIpPort = (codecComm as GenericTcpIpClient).Port;
codecHasIpInfo = true;
}
if (codecHasIpInfo)
{
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly);
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly);
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
}
var tempAsset = new FusionAsset();
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
// TODO: Map relevant attributes on asset symbol
codecAsset.TrySetMakeModel(codec);
codecAsset.TryLinkAssetErrorToCommunication(codec);
}
catch (Exception e)
{
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
}
}
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
{
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
}
// These methods are overridden because they access the room class which is of a different type
protected override void CreateSymbolAndBasicSigs(uint ipId)
{
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
FusionRoom.Register();
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange;
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
// Room to fusion room
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
// Moved to
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly);
// Don't think we need to get current status of this as nothing should be alive yet.
(Room as EssentialsHuddleVtc1Room).CurrentSingleSourceChange += Room_CurrentSourceInfoChange;
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff"));
// NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
}
protected override void SetUpSources()
{
// Sources
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey);
if (dict != null)
{
// NEW PROCESS:
// Make these lists and insert the fusion attributes by iterating these
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
uint i = 1;
foreach (var kvp in setTopBoxes)
{
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 5) // We only have five spots
break;
}
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
i = 1;
foreach (var kvp in discPlayers)
{
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 5) // We only have five spots
break;
}
var laptops = dict.Where(d => d.Value.SourceDevice is Laptop);
i = 1;
foreach (var kvp in laptops)
{
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 10) // We only have ten spots???
break;
}
foreach (var kvp in dict)
{
var usageDevice = kvp.Value.SourceDevice as IUsageTracking;
if (usageDevice != null)
{
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device);
usageDevice.UsageTracker.UsageIsTracked = true;
usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
}
}
}
else
{
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
(Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key);
}
}
protected override void SetUpDisplay()
{
try
{
//Setup Display Usage Monitoring
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
// Consider updating this in multiple display systems
foreach (DisplayBase display in displays)
{
display.UsageTracker = new UsageTracking(display);
display.UsageTracker.UsageIsTracked = true;
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
}
var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
if (defaultDisplay == null)
{
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
return;
}
var dispPowerOnAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOn(); });
var dispPowerOffAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOff(); });
// Display to fusion room sigs
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
if (defaultDisplay is IDisplayUsage)
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
MapDisplayToRoomJoins(1, 158, defaultDisplay);
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
//Check for existing asset in GUIDs collection
var tempAsset = new FusionAsset();
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
// Use extension methods
dispAsset.TrySetMakeModel(defaultDisplay);
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
}
catch (Exception e)
{
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
}
}
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
{
string displayName = string.Format("Display {0} - ", displayIndex);
if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay)
{
// Power on
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
// Power Off
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
// Current Source
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff"); }); ;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.Fusion;
using PepperDash.Core;
using PepperDash.Essentials;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.Devices.Common.Occupancy;
namespace PepperDash.Essentials.Fusion
{
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
{
BooleanSigData CodecIsInCall;
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
: base(room, ipId)
{
}
/// <summary>
/// Called in base class constructor before RVI and GUID files are built
/// </summary>
protected override void ExecuteCustomSteps()
{
SetUpCodec();
}
/// <summary>
/// Creates a static asset for the codec and maps the joins to the main room symbol
/// </summary>
void SetUpCodec()
{
try
{
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
if (codec == null)
{
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
return;
}
codec.UsageTracker = new UsageTracking(codec);
codec.UsageTracker.UsageIsTracked = true;
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
var codecPowerOnAction = new Action<bool>(b => { if (!b) codec.StandbyDeactivate(); });
var codecPowerOffAction = new Action<bool>(b => { if (!b) codec.StandbyActivate(); });
// Map FusionRoom Attributes:
// Codec volume
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
codecVolume.OutputSig.UserObject = new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
// In Call Status
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
codec.CallStatusChange += new EventHandler<PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
// Online status
if (codec is ICommunicationMonitor)
{
var c = codec as ICommunicationMonitor;
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
c.CommunicationMonitor.StatusChange += (o, a) =>
{
codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
};
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1");
}
// Codec IP Address
bool codecHasIpInfo = false;
var codecComm = codec.Communication;
string codecIpAddress = string.Empty;
int codecIpPort = 0;
StringSigData codecIpAddressSig;
StringSigData codecIpPortSig;
if(codecComm is GenericSshClient)
{
codecIpAddress = (codecComm as GenericSshClient).Hostname;
codecIpPort = (codecComm as GenericSshClient).Port;
codecHasIpInfo = true;
}
else if (codecComm is GenericTcpIpClient)
{
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
codecIpPort = (codecComm as GenericTcpIpClient).Port;
codecHasIpInfo = true;
}
if (codecHasIpInfo)
{
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly);
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly);
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
}
var tempAsset = new FusionAsset();
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
// TODO: Map relevant attributes on asset symbol
codecAsset.TrySetMakeModel(codec);
codecAsset.TryLinkAssetErrorToCommunication(codec);
}
catch (Exception e)
{
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
}
}
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
{
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
}
// These methods are overridden because they access the room class which is of a different type
protected override void CreateSymbolAndBasicSigs(uint ipId)
{
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
FusionRoom.Register();
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange;
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
// Room to fusion room
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
// Moved to
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly);
// Don't think we need to get current status of this as nothing should be alive yet.
(Room as EssentialsHuddleVtc1Room).CurrentSingleSourceChange += Room_CurrentSourceInfoChange;
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff"));
// NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
}
protected override void SetUpSources()
{
// Sources
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey);
if (dict != null)
{
// NEW PROCESS:
// Make these lists and insert the fusion attributes by iterating these
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
uint i = 1;
foreach (var kvp in setTopBoxes)
{
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 5) // We only have five spots
break;
}
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
i = 1;
foreach (var kvp in discPlayers)
{
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 5) // We only have five spots
break;
}
var laptops = dict.Where(d => d.Value.SourceDevice is Laptop);
i = 1;
foreach (var kvp in laptops)
{
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 10) // We only have ten spots???
break;
}
foreach (var kvp in dict)
{
var usageDevice = kvp.Value.SourceDevice as IUsageTracking;
if (usageDevice != null)
{
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device);
usageDevice.UsageTracker.UsageIsTracked = true;
usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
}
}
}
else
{
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
(Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key);
}
}
protected override void SetUpDisplay()
{
try
{
//Setup Display Usage Monitoring
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
// Consider updating this in multiple display systems
foreach (DisplayBase display in displays)
{
display.UsageTracker = new UsageTracking(display);
display.UsageTracker.UsageIsTracked = true;
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
}
var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
if (defaultDisplay == null)
{
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
return;
}
var dispPowerOnAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOn(); });
var dispPowerOffAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOff(); });
// Display to fusion room sigs
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
if (defaultDisplay is IDisplayUsage)
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
MapDisplayToRoomJoins(1, 158, defaultDisplay);
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
//Check for existing asset in GUIDs collection
var tempAsset = new FusionAsset();
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
// Use extension methods
dispAsset.TrySetMakeModel(defaultDisplay);
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
}
catch (Exception e)
{
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
}
}
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
{
string displayName = string.Format("Display {0} - ", displayIndex);
if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay)
{
// Power on
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
// Power Off
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
// Current Source
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff"); }); ;
}
}
}
}

View File

@@ -1,102 +1,119 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.Behaviours;
namespace PepperDash.Essentials.Fusion
{
/// <summary>
/// Handles mapping Fusion Custom Property values to system properties
/// </summary>
public class FusionCustomPropertiesBridge
{
/// <summary>
/// Evaluates the room info and custom properties from Fusion and updates the system properties aa needed
/// </summary>
/// <param name="roomInfo"></param>
public void EvaluateRoomInfo(string roomKey, RoomInformation roomInfo)
{
var runtimeConfigurableDevices = DeviceManager.AllDevices.Where(d => d is IRuntimeConfigurableDevice);
try
{
foreach (var device in runtimeConfigurableDevices)
{
// Get the current device config so new values can be overwritten over existing
var deviceConfig = (device as IRuntimeConfigurableDevice).GetDeviceConfig();
if (device is RoomOnToDefaultSourceWhenOccupied)
{
var devConfig = (deviceConfig as RoomOnToDefaultSourceWhenOccupiedConfig);
var enableFeature = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupied"));
if (enableFeature != null)
devConfig.EnableRoomOnWhenOccupied = bool.Parse(enableFeature.CustomFieldValue);
var enableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomOnWhenOccupiedStartTime"));
if (enableTime != null)
devConfig.OccupancyStartTime = enableTime.CustomFieldValue;
var disableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomOnWhenOccupiedEndTime"));
if (disableTime != null)
devConfig.OccupancyEndTime = disableTime.CustomFieldValue;
var enableSunday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedSun"));
if (enableSunday != null)
devConfig.EnableSunday = bool.Parse(enableSunday.CustomFieldValue);
var enableMonday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedMon"));
if (enableMonday != null)
devConfig.EnableMonday = bool.Parse(enableMonday.CustomFieldValue);
var enableTuesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedTue"));
if (enableTuesday != null)
devConfig.EnableTuesday = bool.Parse(enableTuesday.CustomFieldValue);
var enableWednesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedWed"));
if (enableWednesday != null)
devConfig.EnableWednesday = bool.Parse(enableWednesday.CustomFieldValue);
var enableThursday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedThu"));
if (enableThursday != null)
devConfig.EnableThursday = bool.Parse(enableThursday.CustomFieldValue);
var enableFriday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedFri"));
if (enableFriday != null)
devConfig.EnableFriday = bool.Parse(enableFriday.CustomFieldValue);
var enableSaturday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedSat"));
if (enableSaturday != null)
devConfig.EnableSaturday = bool.Parse(enableSaturday.CustomFieldValue);
deviceConfig = devConfig;
}
// Set the config on the device
(device as IRuntimeConfigurableDevice).SetDeviceConfig(deviceConfig);
}
//var roomConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(r => r.Key.Equals(roomKey);
//if(roomConfig != null)
//{
// roomConfig.Name = roomInfo.Name;
// // Update HelpMessage in room properties
// roomConfig.Properties.
//}
}
catch (Exception e)
{
Debug.Console(1, "FusionCustomPropetiesBridge: Error mapping properties: {0}", e);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Room.Behaviours;
namespace PepperDash.Essentials.Fusion
{
/// <summary>
/// Handles mapping Fusion Custom Property values to system properties
/// </summary>
public class FusionCustomPropertiesBridge
{
/// <summary>
/// Evaluates the room info and custom properties from Fusion and updates the system properties aa needed
/// </summary>
/// <param name="roomInfo"></param>
public void EvaluateRoomInfo(string roomKey, RoomInformation roomInfo)
{
try
{
var reconfigurableDevices = DeviceManager.AllDevices.Where(d => d is ReconfigurableDevice);
foreach (var device in reconfigurableDevices)
{
// Get the current device config so new values can be overwritten over existing
var deviceConfig = (device as ReconfigurableDevice).Config;
if (device is RoomOnToDefaultSourceWhenOccupied)
{
Debug.Console(1, "Mapping Room on via Occupancy values from Fusion");
var devProps = JsonConvert.DeserializeObject<RoomOnToDefaultSourceWhenOccupiedConfig>(deviceConfig.Properties.ToString());
var enableFeature = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupied"));
if (enableFeature != null)
devProps.EnableRoomOnWhenOccupied = bool.Parse(enableFeature.CustomFieldValue);
var enableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomOnWhenOccupiedStartTime"));
if (enableTime != null)
devProps.OccupancyStartTime = enableTime.CustomFieldValue;
var disableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomOnWhenOccupiedEndTime"));
if (disableTime != null)
devProps.OccupancyEndTime = disableTime.CustomFieldValue;
var enableSunday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedSun"));
if (enableSunday != null)
devProps.EnableSunday = bool.Parse(enableSunday.CustomFieldValue);
var enableMonday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedMon"));
if (enableMonday != null)
devProps.EnableMonday = bool.Parse(enableMonday.CustomFieldValue);
var enableTuesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedTue"));
if (enableTuesday != null)
devProps.EnableTuesday = bool.Parse(enableTuesday.CustomFieldValue);
var enableWednesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedWed"));
if (enableWednesday != null)
devProps.EnableWednesday = bool.Parse(enableWednesday.CustomFieldValue);
var enableThursday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedThu"));
if (enableThursday != null)
devProps.EnableThursday = bool.Parse(enableThursday.CustomFieldValue);
var enableFriday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedFri"));
if (enableFriday != null)
devProps.EnableFriday = bool.Parse(enableFriday.CustomFieldValue);
var enableSaturday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedSat"));
if (enableSaturday != null)
devProps.EnableSaturday = bool.Parse(enableSaturday.CustomFieldValue);
deviceConfig.Properties = JToken.FromObject(devProps);
}
else if (device is EssentialsRoomBase)
{
// Set the room name
if (!string.IsNullOrEmpty(roomInfo.Name))
{
Debug.Console(1, "Current Room Name: {0}. New Room Name: {1}", deviceConfig.Name, roomInfo.Name);
// Set the name in config
deviceConfig.Name = roomInfo.Name;
Debug.Console(1, "Room Name Successfully Changed.");
}
// Set the help message
var helpMessage = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomHelpMessage"));
if (helpMessage != null)
{
//Debug.Console(1, "Current Help Message: {0}. New Help Message: {1}", deviceConfig.Properties["help"]["message"].Value<string>(ToString()), helpMessage.CustomFieldValue);
deviceConfig.Properties["helpMessage"] = (string)helpMessage.CustomFieldValue;
}
}
// Set the config on the device
(device as ReconfigurableDevice).SetConfig(deviceConfig);
}
}
catch (Exception e)
{
Debug.Console(1, "FusionCustomPropetiesBridge: Error mapping properties: {0}", e);
}
}
}
}

View File

@@ -87,9 +87,7 @@ namespace PepperDash.Essentials
else if (typeName == "roomonwhenoccupancydetectedfeature")
{
var props = JsonConvert.DeserializeObject<Room.Behaviours.RoomOnToDefaultSourceWhenOccupiedConfig>(properties.ToString());
return new Room.Behaviours.RoomOnToDefaultSourceWhenOccupied(key, props);
return new Room.Behaviours.RoomOnToDefaultSourceWhenOccupied(dc);
}
return null;

View File

@@ -49,12 +49,12 @@ namespace PepperDash.Essentials
avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom;
// Environment Driver
if (avDriver.CurrentRoom.Config.Environment != null && avDriver.CurrentRoom.Config.Environment.DeviceKeys.Count > 0)
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
{
Debug.Console(0, panelController, "Adding environment driver");
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props);
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.Config.Environment);
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment);
}
mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom);
@@ -118,12 +118,12 @@ namespace PepperDash.Essentials
avDriver.CurrentRoom = room as EssentialsHuddleVtc1Room;
// Environment Driver
if (avDriver.CurrentRoom.Config.Environment != null && avDriver.CurrentRoom.Config.Environment.DeviceKeys.Count > 0)
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
{
Debug.Console(0, panelController, "Adding environment driver");
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props);
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.Config.Environment);
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment);
}
mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom);

View File

@@ -101,17 +101,35 @@
</Reference>
<Reference Include="SimplSharpTimerEventInterface, Version=1.0.6197.20052, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpTimerEventInterface.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpTimerEventInterface.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
</ItemGroup>
<ItemGroup>
<Compile Include="AppServer\Messengers\ConfigMessenger.cs" />
<Compile Include="AppServer\Messengers\Ddvc01AtcMessenger.cs" />
<Compile Include="AppServer\Messengers\AudioCodecBaseMessenger.cs" />
<Compile Include="AppServer\Messengers\Ddvc01VtcMessenger.cs" />
<Compile Include="AppServer\Messengers\MessengerBase.cs" />
<Compile Include="AppServer\Messengers\SystemMonitorMessenger.cs" />
<Compile Include="AppServer\Messengers\VideoCodecBaseMessenger.cs" />
<Compile Include="Audio\EssentialsVolumeLevelConfig.cs" />
<Compile Include="Bridges\BridgeBase.cs" />
<Compile Include="Bridges\BridgeFactory.cs" />
<Compile Include="Bridges\CameraControllerBridge.cs" />
<Compile Include="Bridges\DisplayControllerBridge.cs" />
<Compile Include="Bridges\DigitalLoggerBridge.cs" />
<Compile Include="Bridges\DmChassisControllerBridge.cs" />
<Compile Include="Bridges\DmTxControllerBridge.cs" />
<Compile Include="Bridges\GenericLightingBridge.cs" />
<Compile Include="Bridges\GenericRelayDeviceBridge.cs" />
<Compile Include="Bridges\IBasicCommunicationBridge.cs" />
<Compile Include="Bridges\DmRmcControllerBridge.cs" />
<Compile Include="Bridges\IDigitalInputBridge.cs" />
<Compile Include="Bridges\JoinMapBase.cs" />
<Compile Include="Bridges\SystemMonitorBridge.cs" />
<Compile Include="Configuration ORIGINAL\Builders\TPConfig.cs" />
<Compile Include="Configuration ORIGINAL\Configuration.cs" />
<Compile Include="Configuration ORIGINAL\ConfigurationHelpers.cs" />
@@ -132,13 +150,13 @@
<Compile Include="Devices\NUMERIC AppleTV.cs" />
<Compile Include="ControlSystem.cs" />
<Compile Include="Factory\UiDeviceFactory.cs" />
<Compile Include="OTHER\Fusion\EssentialsHuddleVtc1FusionController.cs" />
<Compile Include="OTHER\Fusion\FusionCustomPropertiesBridge.cs" />
<Compile Include="OTHER\Fusion\FusionEventHandlers.cs" />
<Compile Include="OTHER\Fusion\FusionProcessorQueries.cs" />
<Compile Include="OTHER\Fusion\FusionRviDataClasses.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\EssentialsHuddleVtc1FusionController.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\FusionCustomPropertiesBridge.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\FusionEventHandlers.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\FusionProcessorQueries.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\FusionRviDataClasses.cs" />
<Compile Include="REMOVE EssentialsApp.cs" />
<Compile Include="OTHER\Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" />
<Compile Include="HttpApiHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />

View File

@@ -4,5 +4,5 @@
[assembly: AssemblyCompany("PepperDash Technology Corp")]
[assembly: AssemblyProduct("PepperDashEssentials")]
[assembly: AssemblyCopyright("Copyright © PepperDash Technology Corp 2018")]
[assembly: AssemblyVersion("1.2.11.*")]
[assembly: AssemblyVersion("1.3.2.*")]

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ControlSystem>
<Name>Test RMC3</Name>
<Address>auto 192.168.1.40</Address>
<ProgramSlot>Program01</ProgramSlot>
<Storage>Internal Flash</Storage>
<?xml version="1.0" encoding="utf-8"?>
<ControlSystem>
<Name>192.168.10.1</Name>
<Address>auto 192.168.10.1</Address>
<ProgramSlot>Program01</ProgramSlot>
<Storage>Internal Flash</Storage>
</ControlSystem>

View File

@@ -11,6 +11,7 @@ using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Devices.Common.Occupancy;
namespace PepperDash.Essentials.Room.Behaviours
@@ -18,9 +19,9 @@ namespace PepperDash.Essentials.Room.Behaviours
/// <summary>
/// A device that when linked to a room can power the room on when enabled during scheduled hours.
/// </summary>
public class RoomOnToDefaultSourceWhenOccupied : Device, IRuntimeConfigurableDevice
public class RoomOnToDefaultSourceWhenOccupied : ReconfigurableDevice
{
RoomOnToDefaultSourceWhenOccupiedConfig Config;
RoomOnToDefaultSourceWhenOccupiedConfig PropertiesConfig;
public bool FeatureEnabled { get; private set; }
@@ -42,10 +43,10 @@ namespace PepperDash.Essentials.Room.Behaviours
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom;
public RoomOnToDefaultSourceWhenOccupied(string key, RoomOnToDefaultSourceWhenOccupiedConfig config)
: base(key)
public RoomOnToDefaultSourceWhenOccupied(DeviceConfig config) :
base (config)
{
Config = config;
PropertiesConfig = JsonConvert.DeserializeObject<RoomOnToDefaultSourceWhenOccupiedConfig>(config.Properties.ToString());
FeatureEventGroup = new ScheduledEventGroup(this.Key);
@@ -63,7 +64,7 @@ namespace PepperDash.Essentials.Room.Behaviours
else
Debug.Console(1, this, "Room has no RoomOccupancy object set");
var fusionRoomKey = Config.RoomKey + "-fusion";
var fusionRoomKey = PropertiesConfig.RoomKey + "-fusion";
FusionRoom = DeviceManager.GetDeviceForKey(fusionRoomKey) as Fusion.EssentialsHuddleSpaceFusionSystemControllerBase;
@@ -79,45 +80,48 @@ namespace PepperDash.Essentials.Room.Behaviours
return base.CustomActivate();
}
/// <summary>
/// Sets up device based on config values
/// </summary>
void SetUpDevice()
{
Room = DeviceManager.GetDeviceForKey(Config.RoomKey) as EssentialsRoomBase;
Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as EssentialsRoomBase;
if (Room != null)
{
try
{
FeatureEnabledTime = DateTime.Parse(Config.OccupancyStartTime);
FeatureEnabledTime = DateTime.Parse(PropertiesConfig.OccupancyStartTime);
if (FeatureEnabledTime != null)
{
Debug.Console(1, this, "Enabled Time: {0}", FeatureEnabledTime.ToString());
}
else
Debug.Console(1, this, "Unable to parse {0} to DateTime", Config.OccupancyStartTime);
Debug.Console(1, this, "Unable to parse {0} to DateTime", PropertiesConfig.OccupancyStartTime);
}
catch (Exception e)
{
Debug.Console(1, this, "Unable to parse OccupancyStartTime property: {0} \n Error: {1}", Config.OccupancyStartTime, e);
Debug.Console(1, this, "Unable to parse OccupancyStartTime property: {0} \n Error: {1}", PropertiesConfig.OccupancyStartTime, e);
}
try
{
FeatureDisabledTime = DateTime.Parse(Config.OccupancyEndTime);
FeatureDisabledTime = DateTime.Parse(PropertiesConfig.OccupancyEndTime);
if (FeatureDisabledTime != null)
{
Debug.Console(1, this, "Disabled Time: {0}", FeatureDisabledTime.ToString());
}
else
Debug.Console(1, this, "Unable to parse {0} to DateTime", Config.OccupancyEndTime);
Debug.Console(1, this, "Unable to parse {0} to DateTime", PropertiesConfig.OccupancyEndTime);
}
catch (Exception e)
{
Debug.Console(1, this, "Unable to parse a DateTime config value \n Error: {1}", e);
}
if (!Config.EnableRoomOnWhenOccupied)
if (!PropertiesConfig.EnableRoomOnWhenOccupied)
FeatureEventGroup.ClearAllEvents();
else
{
@@ -133,30 +137,18 @@ namespace PepperDash.Essentials.Room.Behaviours
FeatureEnabled = CheckIfFeatureShouldBeEnabled();
}
else
Debug.Console(1, this, "Unable to get room from Device Manager with key: {0}", Config.RoomKey);
Debug.Console(1, this, "Unable to get room from Device Manager with key: {0}", PropertiesConfig.RoomKey);
}
/// <summary>
/// Returns a JObject of the device config properties as they currently exist at runtime
/// </summary>
/// <returns></returns>
public JToken GetLocalConfigProperties()
protected override void CustomSetConfig(DeviceConfig config)
{
return JToken.FromObject(Config);
}
var newPropertiesConfig = JsonConvert.DeserializeObject<RoomOnToDefaultSourceWhenOccupiedConfig>(config.Properties.ToString());
public object GetDeviceConfig()
{
return Config;
}
if(newPropertiesConfig != null)
PropertiesConfig = newPropertiesConfig;
public void SetDeviceConfig(object config)
{
var newConfig = config as RoomOnToDefaultSourceWhenOccupiedConfig;
Config = newConfig;
ConfigWriter.UpdateDeviceProperties(this.Key, GetLocalConfigProperties());
ConfigWriter.UpdateDeviceConfig(config);
SetUpDevice();
}
@@ -182,7 +174,7 @@ namespace PepperDash.Essentials.Room.Behaviours
{
if (SchEvent.Name == FeatureEnableEventName)
{
if (Config.EnableRoomOnWhenOccupied)
if (PropertiesConfig.EnableRoomOnWhenOccupied)
FeatureEnabled = true;
Debug.Console(1, this, "*****Feature Enabled by event.*****");
@@ -204,7 +196,7 @@ namespace PepperDash.Essentials.Room.Behaviours
{
bool enabled = false;
if(Config.EnableRoomOnWhenOccupied)
if(PropertiesConfig.EnableRoomOnWhenOccupied)
{
Debug.Console(1, this, "Current Time: {0} \n FeatureEnabledTime: {1} \n FeatureDisabledTime: {2}", DateTime.Now, FeatureEnabledTime, FeatureDisabledTime);
@@ -446,19 +438,19 @@ namespace PepperDash.Essentials.Room.Behaviours
{
ScheduledEventCommon.eWeekDays value = new ScheduledEventCommon.eWeekDays();
if (Config.EnableSunday)
if (PropertiesConfig.EnableSunday)
value = value | ScheduledEventCommon.eWeekDays.Sunday;
if (Config.EnableMonday)
if (PropertiesConfig.EnableMonday)
value = value | ScheduledEventCommon.eWeekDays.Monday;
if (Config.EnableTuesday)
if (PropertiesConfig.EnableTuesday)
value = value | ScheduledEventCommon.eWeekDays.Tuesday;
if (Config.EnableWednesday)
if (PropertiesConfig.EnableWednesday)
value = value | ScheduledEventCommon.eWeekDays.Wednesday;
if (Config.EnableThursday)
if (PropertiesConfig.EnableThursday)
value = value | ScheduledEventCommon.eWeekDays.Thursday;
if (Config.EnableFriday)
if (PropertiesConfig.EnableFriday)
value = value | ScheduledEventCommon.eWeekDays.Friday;
if (Config.EnableSaturday)
if (PropertiesConfig.EnableSaturday)
value = value | ScheduledEventCommon.eWeekDays.Saturday;
return value;
@@ -473,7 +465,7 @@ namespace PepperDash.Essentials.Room.Behaviours
{
if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration)
{
if(Config.EnableRoomOnWhenOccupied)
if(PropertiesConfig.EnableRoomOnWhenOccupied)
FeatureEnabled = true;
Debug.Console(1, this, "RoomOnToDefaultSourceWhenOccupied Feature Enabled.");

View File

@@ -20,5 +20,7 @@ namespace PepperDash.Essentials.Room.Config
public string DefaultSourceItem { get; set; }
[JsonProperty("videoCodecKey")]
public string VideoCodecKey { get; set; }
[JsonProperty("audioCodecKey")]
public string AudioCodecKey { get; set; }
}
}

View File

@@ -24,64 +24,14 @@ namespace PepperDash.Essentials.Room.Config
var typeName = roomConfig.Type.ToLower();
if (typeName == "huddle")
{
var props = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>
(roomConfig.Properties.ToString());
var disp = DeviceManager.GetDeviceForKey(props.DefaultDisplayKey) as IRoutingSinkWithSwitching;
var audio = DeviceManager.GetDeviceForKey(props.DefaultAudioKey) as IRoutingSinkNoSwitching;
var huddle = new EssentialsHuddleSpaceRoom(roomConfig.Key, roomConfig.Name, disp, audio, props);
var huddle = new EssentialsHuddleSpaceRoom(roomConfig);
if (props.Occupancy != null)
huddle.SetRoomOccupancy(DeviceManager.GetDeviceForKey(props.Occupancy.DeviceKey) as
PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider, props.Occupancy.TimeoutMinutes);
huddle.LogoUrl = props.Logo.GetUrl();
huddle.SourceListKey = props.SourceListKey;
huddle.DefaultSourceItem = props.DefaultSourceItem;
huddle.DefaultVolume = (ushort)(props.Volumes.Master.Level * 65535 / 100);
return huddle;
}
//else if (typeName == "presentation")
//{
// var props = JsonConvert.DeserializeObject<EssentialsPresentationRoomPropertiesConfig>
// (this.Properties.ToString());
// var displaysDict = new Dictionary<uint, IRoutingSinkNoSwitching>();
// uint i = 1;
// foreach (var dispKey in props.DisplayKeys) // read in the ordered displays list
// {
// var disp = DeviceManager.GetDeviceForKey(dispKey) as IRoutingSinkWithSwitching;
// displaysDict.Add(i++, disp);
// }
// // Get the master volume control
// IBasicVolumeWithFeedback masterVolumeControlDev = props.Volumes.Master.GetDevice();
// var presRoom = new EssentialsPresentationRoom(Key, Name, displaysDict, masterVolumeControlDev, props);
// return presRoom;
//}
else if (typeName == "huddlevtc1")
{
var props = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>
(roomConfig.Properties.ToString());
var disp = DeviceManager.GetDeviceForKey(props.DefaultDisplayKey) as IRoutingSinkWithSwitching;
var codec = DeviceManager.GetDeviceForKey(props.VideoCodecKey) as
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
var rm = new EssentialsHuddleVtc1Room(roomConfig.Key, roomConfig.Name, disp, codec, codec, props);
// Add Occupancy object from config
if (props.Occupancy != null)
rm.SetRoomOccupancy(DeviceManager.GetDeviceForKey(props.Occupancy.DeviceKey) as
PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider, props.Occupancy.TimeoutMinutes);
rm.LogoUrl = props.Logo.GetUrl();
rm.SourceListKey = props.SourceListKey;
rm.DefaultSourceItem = props.DefaultSourceItem;
rm.DefaultVolume = (ushort)(props.Volumes.Master.Level * 65535 / 100);
rm.MicrophonePrivacy = GetMicrophonePrivacy(props, rm); // Get Microphone Privacy object, if any
rm.Emergency = GetEmergency(props, rm); // Get emergency object, if any
var rm = new EssentialsHuddleVtc1Room(roomConfig);
return rm;
}
else if (typeName == "ddvc01Bridge")
@@ -96,7 +46,7 @@ namespace PepperDash.Essentials.Room.Config
/// Gets and operating, standalone emergegncy object that can be plugged into a room.
/// Returns null if there is no emergency defined
/// </summary>
static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, EssentialsRoomBase room)
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, EssentialsRoomBase room)
{
// This emergency
var emergency = props.Emergency;
@@ -115,13 +65,13 @@ namespace PepperDash.Essentials.Room.Config
/// <param name="props"></param>
/// <param name="room"></param>
/// <returns></returns>
static PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController GetMicrophonePrivacy(
public static PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController GetMicrophonePrivacy(
EssentialsRoomPropertiesConfig props, EssentialsHuddleVtc1Room room)
{
var microphonePrivacy = props.MicrophonePrivacy;
if (microphonePrivacy == null)
{
Debug.Console(0, "ERROR: Cannot create microphone privacy with null properties");
Debug.Console(0, "Cannot create microphone privacy with null properties");
return null;
}
// Get the MicrophonePrivacy device from the device manager

View File

@@ -4,6 +4,8 @@ using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
@@ -11,7 +13,7 @@ using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials
{
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasCurrentVolumeControls
{
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
public event SourceInfoChangeHandler CurrentSingleSourceChange;
@@ -66,7 +68,7 @@ namespace PepperDash.Essentials
}
}
public EssentialsRoomPropertiesConfig Config { get; private set; }
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; }
@@ -147,22 +149,32 @@ namespace PepperDash.Essentials
public string CurrentSourceInfoKey { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
public EssentialsHuddleSpaceRoom(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
IRoutingSinkNoSwitching defaultAudio, EssentialsRoomPropertiesConfig config)
: base(key, name)
public EssentialsHuddleSpaceRoom(DeviceConfig config)
: base(config)
{
try
{
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>
(config.Properties.ToString());
DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
Initialize();
}
catch (Exception e)
{
Debug.Console(1, this, "Error building room: \n{0}", e);
}
}
void Initialize()
{
Config = config;
DefaultDisplay = defaultDisplay;
DefaultAudioDevice = defaultAudio;
if (defaultAudio is IBasicVolumeControls)
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
else if (defaultAudio is IHasVolumeDevice)
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
if (DefaultAudioDevice is IBasicVolumeControls)
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
else if (DefaultAudioDevice is IHasVolumeDevice)
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
CurrentVolumeControls = DefaultVolumeControls;
var disp = DefaultDisplay as DisplayBase;
@@ -195,6 +207,15 @@ namespace PepperDash.Essentials
EnablePowerOnToLastSource = true;
}
protected override void CustomSetConfig(DeviceConfig config)
{
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
if (newPropertiesConfig != null)
PropertiesConfig = newPropertiesConfig;
ConfigWriter.UpdateRoomConfig(config);
}
/// <summary>
///
@@ -225,6 +246,21 @@ namespace PepperDash.Essentials
return true;
}
public override bool CustomActivate()
{
// Add Occupancy object from config
if (PropertiesConfig.Occupancy != null)
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
this.LogoUrl = PropertiesConfig.Logo.GetUrl();
this.SourceListKey = PropertiesConfig.SourceListKey;
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
return base.CustomActivate();
}
/// <summary>
///
/// </summary>

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,8 @@ using Crestron.SimplSharp.Scheduler;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Devices.Common.Occupancy;
namespace PepperDash.Essentials
@@ -14,7 +16,7 @@ namespace PepperDash.Essentials
/// <summary>
///
/// </summary>
public abstract class EssentialsRoomBase : Device
public abstract class EssentialsRoomBase : ReconfigurableDevice
{
/// <summary>
///
@@ -80,12 +82,9 @@ namespace PepperDash.Essentials
/// </summary>
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
public EssentialsRoomBase(string key, string name) : base(key, name)
public EssentialsRoomBase(DeviceConfig config)
: base(config)
{
// Setup the ShutdownPromptTimer
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
@@ -201,7 +200,7 @@ namespace PepperDash.Essentials
/// </summary>
/// <param name="statusProvider"></param>
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
{
{
if (statusProvider == null)
{
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");

View File

@@ -76,7 +76,7 @@ namespace PepperDash.Essentials
avDriver.PopupInterlock.HideAndClear());
}
void SetUpHelpButton(EssentialsRoomPropertiesConfig roomConf)
public void SetUpHelpButton(EssentialsRoomPropertiesConfig roomConf)
{
// Help roomConf and popup
if (roomConf.Help != null)
@@ -107,7 +107,7 @@ namespace PepperDash.Essentials
var room = DeviceManager.GetDeviceForKey(Config.DefaultRoomKey)
as EssentialsHuddleSpaceRoom;
if (room != null)
message = room.Config.HelpMessage;
message = room.PropertiesConfig.HelpMessage;
else
message = "Sorry, no help message available. No room connected.";
//TriList.StringInput[UIStringJoin.HelpMessage].StringValue = message;
@@ -227,7 +227,7 @@ namespace PepperDash.Essentials
TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true);
var roomConf = currentRoom.Config;
var roomConf = currentRoom.PropertiesConfig;
// Register for the PopupInterlock IsShowsFeedback event to tie the header carets subpage visiblity to it
Parent.AvDriver.PopupInterlock.StatusChanged -= PopupInterlock_StatusChanged;
@@ -289,7 +289,7 @@ namespace PepperDash.Essentials
TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true);
var roomConf = currentRoom.Config;
var roomConf = currentRoom.PropertiesConfig;
// Register for the PopupInterlock IsShowsFeedback event to tie the header carets subpage visiblity to it
Parent.AvDriver.PopupInterlock.StatusChanged -= PopupInterlock_StatusChanged;

View File

@@ -58,16 +58,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
SmartObjectDynamicList RecentCallsList;
SmartObjectDynamicList DirectoryList;
CodecDirectory CurrentDirectoryResult;
/// <summary>
/// Tracks the directory browse history when browsing beyond the root directory
/// </summary>
List<CodecDirectory> DirectoryBrowseHistory;
bool NextDirectoryResultIsFolderContents;
BoolFeedback DirectoryBackButtonVisibleFeedback;
// These are likely temp until we get a keyboard built
@@ -111,7 +102,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
SetupCallStagingPopover();
SetupDialKeypad();
ActiveCallsSRL = new SubpageReferenceList(triList, UISmartObjectJoin.CodecActiveCallsHeaderList, 5,5,5);
SetupDirectoryList();
SetupRecentCallsList();
SetupFavorites();
SetupLayoutControls();
@@ -169,12 +159,14 @@ namespace PepperDash.Essentials.UIDrivers.VC
});
SearchStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.CodecDirectorySearchEntryText]);
SetupDirectoryList();
SearchStringBackspaceVisibleFeedback = new BoolFeedback(() => SearchStringBuilder.Length > 0);
SearchStringBackspaceVisibleFeedback.LinkInputSig(triList.BooleanInput[UIBoolJoin.VCDirectoryBackspaceVisible]);
triList.SetSigFalseAction(UIBoolJoin.VCDirectoryBackPress, GetDirectoryParentFolderContents);
DirectoryBackButtonVisibleFeedback = new BoolFeedback(() => CurrentDirectoryResult != (codec as IHasDirectory).DirectoryRoot);
DirectoryBackButtonVisibleFeedback = (codec as IHasDirectory).CurrentDirectoryResultIsNotDirectoryRoot;
DirectoryBackButtonVisibleFeedback
.LinkInputSig(triList.BooleanInput[UIBoolJoin.VCDirectoryBackVisible]);
@@ -484,9 +476,9 @@ namespace PepperDash.Essentials.UIDrivers.VC
TriList.SetString(timeTextOffset + i, timeText);
string iconName = null;
if (c.OccurenceType == eCodecOccurrenceType.Received)
if (c.OccurrenceType == eCodecOccurrenceType.Received)
iconName = "Misc-18_Light";
else if (c.OccurenceType == eCodecOccurrenceType.Placed)
else if (c.OccurrenceType == eCodecOccurrenceType.Placed)
iconName = "Misc-17_Light";
else
iconName = "Delete";
@@ -532,8 +524,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
/// </summary>
void SetupDirectoryList()
{
DirectoryBrowseHistory = new List<CodecDirectory>();
var codec = Codec as IHasDirectory;
if (codec != null)
{
@@ -548,28 +538,20 @@ namespace PepperDash.Essentials.UIDrivers.VC
codec.PhonebookSyncState.InitialSyncCompleted += new EventHandler<EventArgs>(PhonebookSyncState_InitialSyncCompleted);
}
// If there is something here now, show it otherwise wait for the event
if (CurrentDirectoryResult != null && codec.DirectoryRoot.DirectoryResults.Count > 0)
{
RefreshDirectory();
}
RefreshDirectory();
}
}
/// <summary>
/// Sets the current directory resutls to the DirectorRoot and updates Back Button visibiltiy
/// Sets the current directory results to the DirectoryRoot and updates Back Button visibiltiy
/// </summary>
void SetCurrentDirectoryToRoot()
{
DirectoryBrowseHistory.Clear();
CurrentDirectoryResult = (Codec as IHasDirectory).DirectoryRoot;
(Codec as IHasDirectory).SetCurrentDirectoryToRoot();
SearchKeypadClear();
DirectoryBackButtonVisibleFeedback.FireUpdate();
RefreshDirectory();
}
@@ -584,10 +566,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
SetCurrentDirectoryToRoot();
if (CurrentDirectoryResult != null && codec.DirectoryRoot.DirectoryResults.Count > 0)
{
RefreshDirectory();
}
RefreshDirectory();
}
/// <summary>
@@ -597,13 +577,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
/// <param name="e"></param>
void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e)
{
if (NextDirectoryResultIsFolderContents)
{
NextDirectoryResultIsFolderContents = false;
DirectoryBrowseHistory.Add(e.Directory);
}
CurrentDirectoryResult = e.Directory;
DirectoryBackButtonVisibleFeedback.FireUpdate();
RefreshDirectory();
}
@@ -615,7 +589,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
{
(Codec as IHasDirectory).GetDirectoryFolderContents(folder.FolderId);
NextDirectoryResultIsFolderContents = true;
}
/// <summary>
@@ -625,18 +598,13 @@ namespace PepperDash.Essentials.UIDrivers.VC
{
var codec = Codec as IHasDirectory;
if (DirectoryBrowseHistory.Count > 0)
if (codec != null)
{
var lastItemIndex = DirectoryBrowseHistory.Count - 1;
CurrentDirectoryResult = DirectoryBrowseHistory[lastItemIndex];
DirectoryBrowseHistory.Remove(DirectoryBrowseHistory[lastItemIndex]);
codec.GetDirectoryParentFolderContents();
RefreshDirectory();
}
else
{
SetCurrentDirectoryToRoot();
//RefreshDirectory();
}
}
/// <summary>
@@ -645,10 +613,10 @@ namespace PepperDash.Essentials.UIDrivers.VC
/// <param name="dir"></param>
void RefreshDirectory()
{
if (CurrentDirectoryResult.DirectoryResults.Count > 0)
if ((Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults.Count > 0)
{
ushort i = 0;
foreach (var r in CurrentDirectoryResult.DirectoryResults)
foreach (var r in (Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults)
{
if (i == DirectoryList.MaxCount)
{
@@ -725,13 +693,13 @@ namespace PepperDash.Essentials.UIDrivers.VC
Parent.MeetingOrContactMethodModalSrl.StringInputSig(i, 4).StringValue = "";
Parent.MeetingOrContactMethodModalSrl.StringInputSig(i, 5).StringValue = "Connect";
Parent.MeetingOrContactMethodModalSrl.BoolInputSig(i, 2).BoolValue = true;
var cc = c; // lambda scope
var cc = c; // to maintian lambda scope
Parent.MeetingOrContactMethodModalSrl.GetBoolFeedbackSig(i, 1).SetSigFalseAction(() =>
{
Parent.PopupInterlock.Hide();
var codec = Codec as VideoCodecBase;
if (codec != null)
codec.Dial(c.Number);
codec.Dial(cc.Number);
});
}
Parent.MeetingOrContactMethodModalSrl.Count = i;
@@ -1102,7 +1070,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
SearchStringFeedback.FireUpdate();
SearchStringKeypadCheckEnables();
if(CurrentDirectoryResult != (Codec as IHasDirectory).DirectoryRoot)
if ((Codec as IHasDirectory).CurrentDirectoryResultIsNotDirectoryRoot.BoolValue)
SetCurrentDirectoryToRoot();
}

View File

@@ -30,4 +30,8 @@ devjson:1 {"deviceKey":"room1.InCallFeedback","methodName":"SetTestValue", "para
devjson:1 {"deviceKey":"room1.InCallFeedback","methodName":"ClearTestValue", "params": []}
devjson:3 {"deviceKey":"room1.RoomOccupancy.RoomIsOccupiedFeedback","methodName":"SetTestValue", "params": [ true ]}
devjson:3 {"deviceKey":"room1.RoomOccupancy.RoomIsOccupiedFeedback","methodName":"SetTestValue", "params": [ true ]}
devjson:2 {"deviceKey":"codec-comms-ssh", "methodName":"SendText", "params": ["xcommand dial number: 10.11.50.211\r"]}
devjson:2 {"deviceKey":"codec-comms-ssh", "methodName":"Connect", "params": []}