diff --git a/.gitignore b/.gitignore
index 501c2f26..94b7d400 100644
--- a/.gitignore
+++ b/.gitignore
@@ -388,3 +388,4 @@ MigrationBackup/
# Fody - auto-generated XML schema
FodyWeavers.xsd
+essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/PepperDash_Essentials_Interfaces.csproj
diff --git a/IR Drivers/Comcast X1.ir b/IR Drivers/Comcast X1.ir
index bff5afff..4f6c638e 100644
Binary files a/IR Drivers/Comcast X1.ir and b/IR Drivers/Comcast X1.ir differ
diff --git a/IR Drivers/DirecTV H21.ir b/IR Drivers/DirecTV H21.ir
index 612a9b2b..5744d336 100644
Binary files a/IR Drivers/DirecTV H21.ir and b/IR Drivers/DirecTV H21.ir differ
diff --git a/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs
index 2e1b8394..ba00306d 100644
--- a/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs
+++ b/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs
@@ -70,6 +70,14 @@ namespace PepperDash.Essentials.Bridges
/// Range reports the highest supported HDCP state level for the corresponding input card
///
public uint HdcpSupportCapability { get; set; }
+ ///
+ /// DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback
+ ///
+ public uint InputStreamCardStatus { get; set; }
+ ///
+ /// DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback
+ ///
+ public uint OutputStreamCardStatus { get; set; }
#endregion
#region Serials
@@ -115,6 +123,8 @@ namespace PepperDash.Essentials.Bridges
InputUsb = 700; //701-899
HdcpSupportState = 1000; //1001-1199
HdcpSupportCapability = 1200; //1201-1399
+ InputStreamCardStatus = 1500; //1501-1532
+ OutputStreamCardStatus = 1600; //1601-1632
//Serial
@@ -145,6 +155,8 @@ namespace PepperDash.Essentials.Bridges
OutputEndpointOnline = OutputEndpointOnline + joinOffset;
HdcpSupportState = HdcpSupportState + joinOffset;
HdcpSupportCapability = HdcpSupportCapability + joinOffset;
+ InputStreamCardStatus = InputStreamCardStatus + joinOffset;
+ OutputStreamCardStatus = OutputStreamCardStatus + joinOffset;
OutputDisabledByHdcp = OutputDisabledByHdcp + joinOffset;
TxAdvancedIsPresent = TxAdvancedIsPresent + joinOffset;
}
diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs
index 95d8d169..f2a25927 100644
--- a/PepperDashEssentials/ControlSystem.cs
+++ b/PepperDashEssentials/ControlSystem.cs
@@ -12,6 +12,7 @@ using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
+using PepperDash.Essentials.Core.Fusion;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
@@ -53,7 +54,7 @@ namespace PepperDash.Essentials
if (Debug.DoNotLoadOnNextBoot)
{
- CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
+ CrestronConsole.AddNewConsoleCommand(s => CrestronInvoke.BeginInvoke((o) => GoWithLoad()), "go", "Loads configuration file",
ConsoleAccessLevelEnum.AccessOperator);
}
@@ -444,11 +445,30 @@ namespace PepperDash.Essentials
if (room != null && room is EssentialsRoomBase)
{
+ // default IPID
+ uint fusionIpId = 0xf1;
+
+ // default to no join map key
+ string fusionJoinMapKey = string.Empty;
+
+ if (room.Config.Properties["fusion"] != null)
+ {
+ Debug.Console(2, "Custom Fusion config found. Using custom values");
+
+ var fusionConfig = room.Config.Properties["fusion"].ToObject();
+
+ if (fusionConfig != null)
+ {
+ fusionIpId = fusionConfig.IpIdInt;
+ fusionJoinMapKey = fusionConfig.JoinMapKey;
+ }
+ }
+
if (room is EssentialsHuddleSpaceRoom)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
- DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
+ DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
@@ -459,12 +479,24 @@ namespace PepperDash.Essentials
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
- DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
+ DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
CreateMobileControlBridge(room as EssentialsRoomBase);
}
+ else if (room is EssentialsTechRoom)
+ {
+ DeviceManager.AddDevice(room);
+
+ Debug.Console(0, Debug.ErrorLogLevel.Notice,
+ "Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion");
+ DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
+
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
+
+ CreateMobileControlBridge(room);
+ }
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion");
@@ -569,7 +601,7 @@ namespace PepperDash.Essentials
return ((logoDark != null && logoDark == "system") ||
(logoLight != null && logoLight == "system") || (logo != null && logo == "system"));
}
- catch (Exception e)
+ catch
{
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Unable to find logo information in any room config: {0}", e);
return false;
diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs
index 8d9da386..c4a68d4e 100644
--- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs
+++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs
@@ -16,8 +16,8 @@ namespace PepperDash.Essentials.Fusion
{
BooleanSigData CodecIsInCall;
- public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
- : base(room, ipId)
+ public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
+ : base(room, ipId, joinMapKey)
{
}
@@ -55,25 +55,25 @@ namespace PepperDash.Essentials.Fusion
// Map FusionRoom Attributes:
// Codec volume
- var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
+ var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.AttributeName, eSigIoMask.InputOutputSig);
codecVolume.OutputSig.UserObject = new Action(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);
+ CodecIsInCall = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecInCall.JoinNumber, JoinMap.VcCodecInCall.AttributeName, eSigIoMask.InputSigOnly);
codec.CallStatusChange += new EventHandler(codec_CallStatusChange);
// Online status
if (codec is ICommunicationMonitor)
{
var c = codec as ICommunicationMonitor;
- var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
+ var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, JoinMap.VcCodecOnline.AttributeName, 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");
+ Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, JoinMap.VcCodecOnline.AttributeName);
}
// Codec IP Address
@@ -101,10 +101,10 @@ namespace PepperDash.Essentials.Fusion
if (codecHasIpInfo)
{
- codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly);
+ codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, JoinMap.VcCodecIpAddress.AttributeName, eSigIoMask.InputSigOnly);
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
- codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly);
+ codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, JoinMap.VcCodecIpPort.AttributeName, eSigIoMask.InputSigOnly);
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
}
@@ -123,7 +123,7 @@ namespace PepperDash.Essentials.Fusion
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
- var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
+ var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Codec", tempAsset.InstanceId);
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
@@ -166,20 +166,19 @@ namespace PepperDash.Essentials.Fusion
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);
+ CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "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);
+ CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly);
// Don't think we need to get current status of this as nothing should be alive yet.
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
- // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
@@ -197,9 +196,9 @@ namespace PepperDash.Essentials.Fusion
uint i = 1;
foreach (var kvp in setTopBoxes)
{
- TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
+ TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
i++;
- if (i > 5) // We only have five spots
+ if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
break;
}
@@ -207,7 +206,7 @@ namespace PepperDash.Essentials.Fusion
i = 1;
foreach (var kvp in discPlayers)
{
- TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
+ TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 5) // We only have five spots
break;
@@ -217,9 +216,9 @@ namespace PepperDash.Essentials.Fusion
i = 1;
foreach (var kvp in laptops)
{
- TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
+ TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
i++;
- if (i > 10) // We only have ten spots???
+ if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
break;
}
@@ -283,7 +282,7 @@ namespace PepperDash.Essentials.Fusion
if (defaultDisplay is IDisplayUsage)
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
- MapDisplayToRoomJoins(1, 158, defaultDisplay);
+ MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay);
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
@@ -328,7 +327,7 @@ namespace PepperDash.Essentials.Fusion
}
- protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
+ protected override void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display)
{
string displayName = string.Format("Display {0} - ", displayIndex);
diff --git a/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs b/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs
new file mode 100644
index 00000000..7e465b4d
--- /dev/null
+++ b/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs
@@ -0,0 +1,98 @@
+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.Core.Fusion;
+
+namespace PepperDash.Essentials.Fusion
+{
+ public class EssentialsTechRoomFusionSystemController : EssentialsHuddleSpaceFusionSystemControllerBase
+ {
+ public EssentialsTechRoomFusionSystemController(EssentialsTechRoom room, uint ipId, string joinMapKey)
+ : base(room, ipId, joinMapKey)
+ {
+
+ }
+
+ protected override void SetUpDisplay()
+ {
+ try
+ {
+
+ var displays = (Room as EssentialsTechRoom).Displays;
+
+ Debug.Console(1, this, "Setting up Static Assets for {0} Displays", displays.Count);
+
+ foreach (var display in displays.Values.Cast())
+ {
+ Debug.Console(2, this, "Setting up Static Asset for {0}", display.Key);
+
+ display.UsageTracker = new UsageTracking(display) { UsageIsTracked = true };
+ display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
+
+ var dispPowerOnAction = new Action(b =>
+ {
+ if (!b)
+ {
+ display.PowerOn();
+ }
+ });
+ var dispPowerOffAction = new Action(b =>
+ {
+ if (!b)
+ {
+ display.PowerOff();
+ }
+ });
+
+ var deviceConfig = ConfigReader.ConfigObject.GetDeviceForKey(display.Key);
+
+ FusionAsset tempAsset;
+
+ if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
+ {
+ // Used existing asset
+ tempAsset = FusionStaticAssets[deviceConfig.Uid];
+ }
+ else
+ {
+ // Create a new asset
+ tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
+ display.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;
+
+ var defaultTwoWayDisplay = display as IHasPowerControlWithFeedback;
+ if (defaultTwoWayDisplay != null)
+ {
+ defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
+ if (display is IDisplayUsage)
+ {
+ (display as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
+ }
+
+ defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
+ }
+
+ // Use extension methods
+ dispAsset.TrySetMakeModel(display);
+ dispAsset.TryLinkAssetErrorToCommunication(display);
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.Console(1, this, "Error setting up displays in Fusion: {0}", e);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj
index febf40f9..3b373e69 100644
--- a/PepperDashEssentials/PepperDashEssentials.csproj
+++ b/PepperDashEssentials/PepperDashEssentials.csproj
@@ -133,6 +133,7 @@
+
@@ -141,11 +142,13 @@
+
+
diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs
index dfaa333d..201b583c 100644
--- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs
+++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs
@@ -22,30 +22,25 @@ namespace PepperDash.Essentials.Room.Config
public static Device GetRoomObject(DeviceConfig roomConfig)
{
var typeName = roomConfig.Type.ToLower();
+
if (typeName == "huddle")
{
- var huddle = new EssentialsHuddleSpaceRoom(roomConfig);
-
- return huddle;
+ return new EssentialsHuddleSpaceRoom(roomConfig);
}
- else if (typeName == "huddlevtc1")
- {
- var rm = new EssentialsHuddleVtc1Room(roomConfig);
-
- return rm;
- }
- else if (typeName == "ddvc01Bridge")
- {
- return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
- }
- else if (typeName == "dualdisplay")
- {
- var rm = new EssentialsDualDisplayRoom(roomConfig);
+ if (typeName == "huddlevtc1")
+ {
+ return new EssentialsHuddleVtc1Room(roomConfig);
+ }
+ if (typeName == "ddvc01bridge")
+ {
+ return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
+ }
+ if (typeName == "dualdisplay")
+ {
+ return new EssentialsDualDisplayRoom(roomConfig);
+ }
- return rm;
- }
-
- return null;
+ return typeName != "techroom" ? null : new EssentialsTechRoom(roomConfig);
}
///
@@ -182,6 +177,9 @@ namespace PepperDash.Essentials.Room.Config
[JsonProperty("volumes")]
public EssentialsRoomVolumesConfig Volumes { get; set; }
+ [JsonProperty("fusion")]
+ public EssentialsRoomFusionConfig Fusion { get; set; }
+
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
@@ -225,6 +223,32 @@ namespace PepperDash.Essentials.Room.Config
}
+ public class EssentialsRoomFusionConfig
+ {
+ public uint IpIdInt
+ {
+ get
+ {
+ try
+ {
+ return Convert.ToUInt32(IpId, 16);
+ }
+ catch (Exception)
+ {
+ throw new FormatException(string.Format("ERROR:Unable to convert IP ID: {0} to hex. Error:\n{1}", IpId));
+ }
+
+ }
+ }
+
+ [JsonProperty("ipId")]
+ public string IpId { get; set; }
+
+ [JsonProperty("joinMapKey")]
+ public string JoinMapKey { get; set; }
+
+ }
+
public class EssentialsRoomMicrophonePrivacyConfig
{
[JsonProperty("deviceKey")]
diff --git a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs
new file mode 100644
index 00000000..06e67f39
--- /dev/null
+++ b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs
@@ -0,0 +1,40 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace PepperDash.Essentials.Room.Config
+{
+ public class EssentialsTechRoomConfig
+ {
+ [JsonProperty("dummySourceKey")]
+ public string DummySourceKey { get; set; }
+
+ [JsonProperty("displays")]
+ public List Displays;
+
+ [JsonProperty("tuners")]
+ public List Tuners;
+
+ [JsonProperty("userPin")]
+ public string UserPin;
+
+ [JsonProperty("techPin")]
+ public string TechPin;
+
+ [JsonProperty("presetsFileName")]
+ public string PresetsFileName;
+
+ [JsonProperty("scheduledEvents")]
+ public List ScheduledEvents;
+
+ [JsonProperty("isPrimary")] public bool IsPrimary;
+
+ [JsonProperty("isTvPresetsProvider")] public bool IsTvPresetsProvider;
+
+ public EssentialsTechRoomConfig()
+ {
+ Displays = new List();
+ Tuners = new List();
+ ScheduledEvents = new List();
+ }
+ }
+}
\ No newline at end of file
diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
new file mode 100644
index 00000000..bfa56646
--- /dev/null
+++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
@@ -0,0 +1,473 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Crestron.SimplSharp;
+using Crestron.SimplSharp.Scheduler;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+using PepperDash.Essentials.Core.Config;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Core.Presets;
+using PepperDash.Essentials.Devices.Common;
+using PepperDash.Essentials.Room.Config;
+
+namespace PepperDash.Essentials
+{
+ public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction
+ {
+ private readonly EssentialsTechRoomConfig _config;
+ private readonly Dictionary _displays;
+
+ private readonly DevicePresetsModel _tunerPresets;
+ private readonly Dictionary _tuners;
+
+ private Dictionary _currentPresets;
+ private ScheduledEventGroup _roomScheduledEventGroup;
+
+ ///
+ ///
+ ///
+ protected override Func IsWarmingFeedbackFunc
+ {
+ get
+ {
+ return () =>
+ {
+ return _displays.All(kv => kv.Value.IsWarmingUpFeedback.BoolValue);
+ };
+ }
+ }
+ ///
+ ///
+ ///
+ protected override Func IsCoolingFeedbackFunc
+ {
+ get
+ {
+ return () =>
+ {
+ return _displays.All(kv => kv.Value.IsCoolingDownFeedback.BoolValue);
+ };
+ }
+ }
+
+ public EssentialsTechRoom(DeviceConfig config) : base(config)
+ {
+ _config = config.Properties.ToObject();
+
+ _tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName);
+
+ _tunerPresets.SetFileName(_config.PresetsFileName);
+
+ _tunerPresets.PresetRecalled += TunerPresetsOnPresetRecalled;
+
+ _tuners = GetDevices(_config.Tuners);
+ _displays = GetDevices(_config.Displays);
+
+ RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn);
+
+ SetUpTunerPresetsFeedback();
+
+ SubscribeToDisplayFeedbacks();
+
+ CreateOrUpdateScheduledEvents();
+ }
+
+ public Dictionary CurrentPresetsFeedbacks { get; private set; }
+
+ public Dictionary Tuners
+ {
+ get { return _tuners; }
+ }
+
+ public Dictionary Displays
+ {
+ get { return _displays; }
+ }
+
+ public BoolFeedback RoomPowerIsOnFeedback { get; private set; }
+
+ public bool RoomPowerIsOn
+ {
+ get { return _displays.All(kv => kv.Value.PowerIsOnFeedback.BoolValue); }
+ }
+
+ #region ITvPresetsProvider Members
+
+ public DevicePresetsModel TvPresets
+ {
+ get { return _tunerPresets; }
+ }
+
+ #endregion
+
+ private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
+ {
+ if (!_currentPresets.ContainsKey(device.Key))
+ {
+ return;
+ }
+
+ _currentPresets[device.Key] = channel;
+
+ if (!CurrentPresetsFeedbacks.ContainsKey(device.Key))
+ {
+ CurrentPresetsFeedbacks[device.Key].FireUpdate();
+ }
+ }
+
+ private void SetUpTunerPresetsFeedback()
+ {
+ _currentPresets = new Dictionary();
+ CurrentPresetsFeedbacks = new Dictionary();
+
+ foreach (var setTopBox in _tuners)
+ {
+ var tuner = setTopBox.Value;
+ _currentPresets.Add(tuner.Key, String.Empty);
+ CurrentPresetsFeedbacks.Add(tuner.Key, new StringFeedback(() => _currentPresets[tuner.Key]));
+ }
+ }
+
+ private void SubscribeToDisplayFeedbacks()
+ {
+ foreach (var display in _displays)
+ {
+ display.Value.PowerIsOnFeedback.OutputChange +=
+ (sender, args) =>
+ {
+ RoomPowerIsOnFeedback.InvokeFireUpdate();
+ IsWarmingUpFeedback.InvokeFireUpdate();
+ IsCoolingDownFeedback.InvokeFireUpdate();
+ };
+ }
+ }
+
+ private void CreateOrUpdateScheduledEvents()
+ {
+ var eventsConfig = _config.ScheduledEvents;
+
+ GetOrCreateScheduleGroup();
+
+ foreach (var eventConfig in eventsConfig)
+ {
+ CreateOrUpdateSingleEvent(eventConfig);
+ }
+
+ _roomScheduledEventGroup.UserGroupCallBack += HandleScheduledEvent;
+ }
+
+ private void GetOrCreateScheduleGroup()
+ {
+ if (_roomScheduledEventGroup == null)
+ {
+ _roomScheduledEventGroup = Scheduler.GetEventGroup(Key) ?? new ScheduledEventGroup(Key);
+
+ Scheduler.AddEventGroup(_roomScheduledEventGroup);
+ }
+
+ _roomScheduledEventGroup.RetrieveAllEvents();
+ }
+
+ private void CreateOrUpdateSingleEvent(ScheduledEventConfig scheduledEvent)
+ {
+ if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(scheduledEvent.Key))
+ {
+ SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
+ return;
+ }
+
+ var roomEvent = _roomScheduledEventGroup.ScheduledEvents[scheduledEvent.Key];
+
+ if (!SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) &&
+ !SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days))
+ {
+ return;
+ }
+
+ Debug.Console(1, this,
+ "Existing event does not match new config properties. Deleting existing event '{0}' and creating new event from configuration",
+ roomEvent.Name);
+
+ _roomScheduledEventGroup.DeleteEvent(roomEvent);
+
+ SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
+ }
+
+ public void AddOrUpdateScheduledEvent(ScheduledEventConfig scheduledEvent)
+ {
+ //update config based on key of scheduleEvent
+ GetOrCreateScheduleGroup();
+ var existingEventIndex = _config.ScheduledEvents.FindIndex((e) => e.Key == scheduledEvent.Key);
+
+ if (existingEventIndex < 0)
+ {
+ _config.ScheduledEvents.Add(scheduledEvent);
+ }
+ else
+ {
+ _config.ScheduledEvents[existingEventIndex] = scheduledEvent;
+ }
+
+ //create or update event based on config
+ CreateOrUpdateSingleEvent(scheduledEvent);
+ //save config
+ Config.Properties = JToken.FromObject(_config);
+
+ CustomSetConfig(Config);
+ //Fire Event
+ OnScheduledEventUpdate();
+ }
+
+ public List GetScheduledEvents()
+ {
+ return _config.ScheduledEvents ?? new List();
+ }
+
+ private void OnScheduledEventUpdate()
+ {
+ var handler = ScheduledEventsChanged;
+
+ if (handler == null)
+ {
+ return;
+ }
+
+ handler(this, new ScheduledEventEventArgs {ScheduledEvents = _config.ScheduledEvents});
+ }
+
+ public event EventHandler ScheduledEventsChanged;
+
+ private void HandleScheduledEvent(ScheduledEvent schevent, ScheduledEventCommon.eCallbackReason type)
+ {
+ var eventConfig = _config.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name);
+
+ if (eventConfig == null)
+ {
+ Debug.Console(1, this, "Event with name {0} not found", schevent.Name);
+ return;
+ }
+
+ Debug.Console(1, this, "Running actions for event {0}", schevent.Name);
+
+ if (eventConfig.Acknowledgeable)
+ {
+ schevent.Acknowledge();
+ }
+
+ CrestronInvoke.BeginInvoke((o) =>
+ {
+ Debug.Console(2, this, "There are {0} actions to execute for this event.", eventConfig.Actions.Count);
+
+ foreach (var a in eventConfig.Actions)
+ {
+ Debug.Console(2, this,
+@"Attempting to run action:
+DeviceKey: {0}
+MethodName: {1}
+Params: {2}"
+ , a.DeviceKey, a.MethodName, a.Params);
+ DeviceJsonApi.DoDeviceAction(a);
+ }
+ });
+ }
+
+
+ public void RoomPowerOn()
+ {
+ Debug.Console(2, this, "Room Powering On");
+
+ var dummySource = DeviceManager.GetDeviceForKey(_config.DummySourceKey) as IRoutingOutputs;
+
+ if (dummySource == null)
+ {
+ Debug.Console(1, this, "Unable to get source with key: {0}", _config.DummySourceKey);
+ return;
+ }
+
+ foreach (var display in _displays)
+ {
+ RunDirectRoute(dummySource, display.Value);
+ }
+ }
+
+ public void RoomPowerOff()
+ {
+ Debug.Console(2, this, "Room Powering Off");
+
+ foreach (var display in _displays)
+ {
+ display.Value.PowerOff();
+ }
+ }
+
+ private Dictionary GetDevices(ICollection config) where T : IKeyed
+ {
+ try
+ {
+ var returnValue = DeviceManager.AllDevices.OfType()
+ .Where(d => config.Contains(d.Key))
+ .ToDictionary(d => d.Key, d => d);
+
+ return returnValue;
+ }
+ catch
+ {
+ Debug.Console(0, this, Debug.ErrorLogLevel.Error,
+ "Error getting devices. Check Essentials Configuration");
+ return null;
+ }
+ }
+
+ #region Overrides of EssentialsRoomBase
+
+ protected override Func OnFeedbackFunc
+ {
+ get { return () => RoomPowerIsOn; }
+ }
+
+ protected override void EndShutdown()
+ {
+ }
+
+ public override void SetDefaultLevels()
+ {
+ }
+
+ public override void PowerOnToDefaultOrLastSource()
+ {
+ }
+
+ public override bool RunDefaultPresentRoute()
+ {
+ return false;
+ }
+
+ public override void RoomVacatedForTimeoutPeriod(object o)
+ {
+ }
+
+ #endregion
+
+ #region Implementation of IBridgeAdvanced
+
+ public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+
+ var joinMap = new EssentialsTechRoomJoinMap(joinStart);
+ var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
+
+ if (!String.IsNullOrEmpty(joinMapSerialized))
+ {
+ joinMap = JsonConvert.DeserializeObject(joinMapSerialized);
+ }
+
+ if (bridge != null)
+ {
+ bridge.AddJoinMap(Key, joinMap);
+ }
+ uint i;
+ if (_config.IsPrimary)
+ {
+ i = 0;
+ foreach (var feedback in CurrentPresetsFeedbacks)
+ {
+ feedback.Value.LinkInputSig(trilist.StringInput[(uint) (joinMap.CurrentPreset.JoinNumber + i)]);
+ i++;
+ }
+
+ trilist.OnlineStatusChange += (device, args) =>
+ {
+ if (!args.DeviceOnLine)
+ {
+ return;
+ }
+
+ foreach (var feedback in CurrentPresetsFeedbacks)
+ {
+ feedback.Value.FireUpdate();
+ }
+ };
+
+ return;
+ }
+
+ i = 0;
+ foreach (var setTopBox in _tuners)
+ {
+ var tuner = setTopBox;
+
+ trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value));
+
+ i++;
+ }
+ }
+
+ #endregion
+
+ private class EssentialsTechRoomJoinMap : JoinMapBaseAdvanced
+ {
+ [JoinName("currentPreset")]
+ public JoinDataComplete CurrentPreset = new JoinDataComplete(new JoinData {JoinNumber = 1, JoinSpan = 16},
+ new JoinMetadata {Description = "Current Tuner Preset", JoinType = eJoinType.Serial});
+
+ public EssentialsTechRoomJoinMap(uint joinStart) : base(joinStart, typeof(EssentialsTechRoomJoinMap))
+ {
+ }
+ }
+
+ #region IRunDirectRouteAction Members
+
+ private void RunDirectRoute(IRoutingOutputs source, IRoutingSink dest)
+ {
+ if (dest == null)
+ {
+ Debug.Console(1, this, "Cannot route, unknown destination '{0}'", dest.Key);
+ return;
+ }
+
+ if (source == null)
+ {
+ dest.ReleaseRoute();
+ if (dest is IHasPowerControl)
+ (dest as IHasPowerControl).PowerOff();
+ }
+ else
+ {
+ dest.ReleaseAndMakeRoute(source, eRoutingSignalType.Video);
+ }
+ }
+
+ ///
+ /// Attempts to route directly between a source and destination
+ ///
+ ///
+ ///
+ public void RunDirectRoute(string sourceKey, string destinationKey)
+ {
+ IRoutingSink dest = null;
+
+ dest = DeviceManager.GetDeviceForKey(destinationKey) as IRoutingSink;
+
+ var source = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs;
+
+ if (source == null || dest == null)
+ {
+ Debug.Console(1, this, "Cannot route unknown source or destination '{0}' to {1}", sourceKey, destinationKey);
+ return;
+ }
+ RunDirectRoute(source, dest);
+ }
+
+ #endregion
+ }
+
+ public class ScheduledEventEventArgs : EventArgs
+ {
+ public List ScheduledEvents;
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs
index 151b5461..11ede5a1 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs
@@ -78,7 +78,7 @@ namespace PepperDash.Essentials.Core.Bridges
///
/// Bridge API using EISC
///
- public class EiscApiAdvanced : BridgeApi
+ public class EiscApiAdvanced : BridgeApi, ICommunicationMonitor
{
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
@@ -98,13 +98,35 @@ namespace PepperDash.Essentials.Core.Bridges
Eisc.SigChange += Eisc_SigChange;
+ CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, Eisc, 120000, 300000);
+
AddPostActivationAction(LinkDevices);
+ AddPostActivationAction(LinkRooms);
+ AddPostActivationAction(RegisterEisc);
+ }
+
+ public override bool CustomActivate()
+ {
+ CommunicationMonitor.Start();
+ return base.CustomActivate();
+ }
+
+ public override bool Deactivate()
+ {
+ CommunicationMonitor.Stop();
+ return base.Deactivate();
}
private void LinkDevices()
{
Debug.Console(1, this, "Linking Devices...");
+ if (PropertiesConfig.Devices == null)
+ {
+ Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "No devices linked to this bridge");
+ return;
+ }
+
foreach (var d in PropertiesConfig.Devices)
{
var device = DeviceManager.GetDeviceForKey(d.DeviceKey);
@@ -130,6 +152,14 @@ namespace PepperDash.Essentials.Core.Bridges
bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this);
}
}
+ }
+
+ private void RegisterEisc()
+ {
+ if (Eisc.Registered)
+ {
+ return;
+ }
var registerResult = Eisc.Register();
@@ -142,6 +172,31 @@ namespace PepperDash.Essentials.Core.Bridges
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "EISC registration successful");
}
+ public void LinkRooms()
+ {
+ Debug.Console(1, this, "Linking Rooms...");
+
+ if (PropertiesConfig.Rooms == null)
+ {
+ Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "No rooms linked to this bridge.");
+ return;
+ }
+
+ foreach (var room in PropertiesConfig.Rooms)
+ {
+ var rm = DeviceManager.GetDeviceForKey(room.RoomKey) as IBridgeAdvanced;
+
+ if (rm == null)
+ {
+ Debug.Console(1, this, Debug.ErrorLogLevel.Notice,
+ "Room {0} does not implement IBridgeAdvanced. Skipping...", room.RoomKey);
+ continue;
+ }
+
+ rm.LinkToApi(Eisc, room.JoinStart, room.JoinMapKey, this);
+ }
+ }
+
///
/// Adds a join map
///
@@ -280,6 +335,12 @@ namespace PepperDash.Essentials.Core.Bridges
Debug.Console(2, this, "Error in Eisc_SigChange handler: {0}", e);
}
}
+
+ #region Implementation of ICommunicationMonitor
+
+ public StatusMonitorBase CommunicationMonitor { get; private set; }
+
+ #endregion
}
public class EiscApiPropertiesConfig
@@ -290,6 +351,9 @@ namespace PepperDash.Essentials.Core.Bridges
[JsonProperty("devices")]
public List Devices { get; set; }
+ [JsonProperty("rooms")]
+ public List Rooms { get; set; }
+
public class ApiDevicePropertiesConfig
{
@@ -303,6 +367,18 @@ namespace PepperDash.Essentials.Core.Bridges
public string JoinMapKey { get; set; }
}
+ public class ApiRoomPropertiesConfig
+ {
+ [JsonProperty("roomKey")]
+ public string RoomKey { get; set; }
+
+ [JsonProperty("joinStart")]
+ public uint JoinStart { get; set; }
+
+ [JsonProperty("joinMapKey")]
+ public string JoinMapKey { get; set; }
+ }
+
}
public class EiscApiAdvancedFactory : EssentialsDeviceFactory
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs
index 070e8f61..478f4e29 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs
@@ -47,7 +47,7 @@ namespace PepperDash.Essentials.Core.Bridges
/// Join this join map will start at
/// Type of the child join map
public AppleTvJoinMap(uint joinStart, Type type) : base(joinStart, type)
- {
- }
+ {
+ }
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs
index 54909d02..ee04bd45 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs
@@ -76,6 +76,14 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete HdcpSupportCapability = new JoinDataComplete(new JoinData { JoinNumber = 1201, JoinSpan = 32 },
new JoinMetadata { Description = "DM Chassis Input HDCP Support Capability", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
+ [JoinName("InputStreamCardState")]
+ public JoinDataComplete InputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1501, JoinSpan = 32 },
+ new JoinMetadata { Description = "DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
+
+ [JoinName("OutputStreamCardState")]
+ public JoinDataComplete OutputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1601, JoinSpan = 32 },
+ new JoinMetadata { Description = "DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
+
[JoinName("InputNames")]
public JoinDataComplete InputNames = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 },
new JoinMetadata { Description = "DM Chassis Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs
index ddb578d7..75e9ae72 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs
@@ -56,6 +56,11 @@ namespace PepperDash.Essentials.Core
private void RegisterAndConfigureComPort()
{
+ if (Port == null)
+ {
+ Debug.Console(0,this,Debug.ErrorLogLevel.Error, "Configured com Port for this device does not exist.");
+ return;
+ }
if (Port.Parent is CrestronControlSystem)
{
var result = Port.Register();
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs
index a8fa67e4..8a5efe47 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs
@@ -104,7 +104,7 @@ namespace PepperDash.Essentials.Core
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
return dev.ComPorts[config.ControlPortNumber];
- Debug.Console(0, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
+ Debug.Console(0,Debug.ErrorLogLevel.Notice, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
return null;
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs
index 904bfc74..7cbaa5a1 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs
@@ -7,6 +7,8 @@ using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
+using Newtonsoft.Json.Linq;
+
namespace PepperDash.Essentials.Core.Config
{
///
@@ -27,7 +29,7 @@ namespace PepperDash.Essentials.Core.Config
public List TieLines { get; set; }
[JsonProperty("joinMaps")]
- public Dictionary JoinMaps { get; set; }
+ public Dictionary JoinMaps { get; set; }
///
/// Checks SourceLists for a given list and returns it if found. Otherwise, returns null
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs
index 48a026c2..e99206e8 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs
@@ -1,195 +1,195 @@
-using System;
+using System;
using System.Linq;
using System.Text;
-using Crestron.SimplSharp;
-using Crestron.SimplSharp.CrestronIO;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using PepperDash.Core;
-using PepperDash.Core.Config;
-
-namespace PepperDash.Essentials.Core.Config
-{
- ///
- /// Loads the ConfigObject from the file
- ///
+using Crestron.SimplSharp;
+using Crestron.SimplSharp.CrestronIO;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Core.Config;
+
+namespace PepperDash.Essentials.Core.Config
+{
+ ///
+ /// Loads the ConfigObject from the file
+ ///
public class ConfigReader
{
public const string LocalConfigPresent =
@"
***************************************************
************* Using Local config file *************
-***************************************************";
-
- public static EssentialsConfig ConfigObject { get; private set; }
-
- public static bool LoadConfig2()
- {
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading unmerged system/template portal configuration file.");
- try
- {
- // Check for local config file first
- var filePath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder + Global.DirectorySeparator + Global.ConfigFileName;
-
- bool localConfigFound = false;
-
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Local config file: '{0}'", filePath);
-
- // Check for local config directory first
-
- var configFiles = GetConfigFiles(filePath);
-
- if (configFiles != null)
- {
- if (configFiles.Length > 1)
- {
- Debug.Console(0, Debug.ErrorLogLevel.Error,
- "****Error: Multiple Local Configuration files present. Please ensure only a single file exists and reset program.****");
- return false;
- }
- if(configFiles.Length == 1)
- {
+***************************************************";
+
+ public static EssentialsConfig ConfigObject { get; private set; }
+
+ public static bool LoadConfig2()
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading unmerged system/template portal configuration file.");
+ try
+ {
+ // Check for local config file first
+ var filePath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder + Global.DirectorySeparator + Global.ConfigFileName;
+
+ bool localConfigFound = false;
+
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Local config file: '{0}'", filePath);
+
+ // Check for local config directory first
+
+ var configFiles = GetConfigFiles(filePath);
+
+ if (configFiles != null)
+ {
+ if (configFiles.Length > 1)
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Error,
+ "****Error: Multiple Local Configuration files present. Please ensure only a single file exists and reset program.****");
+ return false;
+ }
+ if(configFiles.Length == 1)
+ {
localConfigFound = true;
-
- }
- }
- else
- {
- Debug.Console(0, Debug.ErrorLogLevel.Notice,
- "Local Configuration file not present.", filePath);
-
- }
-
- // Check for Portal Config
- if(!localConfigFound)
- {
- filePath = Global.FilePathPrefix + Global.ConfigFileName;
-
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Portal config file: '{0}'", filePath);
-
- configFiles = GetConfigFiles(filePath);
-
- if (configFiles != null)
- {
- Debug.Console(2, "{0} config files found matching pattern", configFiles.Length);
-
- if (configFiles.Length > 1)
- {
- Debug.Console(0, Debug.ErrorLogLevel.Error,
- "****Error: Multiple Portal Configuration files present. Please ensure only a single file exists and reset program.****");
- return false;
- }
- else if (configFiles.Length == 1)
- {
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Portal config file: '{0}'", filePath);
- }
- else
- {
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "No config file found.");
- return false;
- }
- }
- else
- {
- Debug.Console(0, Debug.ErrorLogLevel.Error,
- "ERROR: Portal Configuration file not present. Please load file and reset program.");
- return false;
- }
- }
-
- // Get the actual file path
+
+ }
+ }
+ else
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Notice,
+ "Local Configuration file not present.", filePath);
+
+ }
+
+ // Check for Portal Config
+ if(!localConfigFound)
+ {
+ filePath = Global.FilePathPrefix + Global.ConfigFileName;
+
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Portal config file: '{0}'", filePath);
+
+ configFiles = GetConfigFiles(filePath);
+
+ if (configFiles != null)
+ {
+ Debug.Console(2, "{0} config files found matching pattern", configFiles.Length);
+
+ if (configFiles.Length > 1)
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Error,
+ "****Error: Multiple Portal Configuration files present. Please ensure only a single file exists and reset program.****");
+ return false;
+ }
+ else if (configFiles.Length == 1)
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Portal config file: '{0}'", filePath);
+ }
+ else
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "No config file found.");
+ return false;
+ }
+ }
+ else
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Error,
+ "ERROR: Portal Configuration file not present. Please load file and reset program.");
+ return false;
+ }
+ }
+
+ // Get the actual file path
filePath = configFiles[0].FullName;
// Generate debug statement if using a local file.
if (localConfigFound)
{
GetLocalFileMessage(filePath);
- }
-
- // Read the file
- using (StreamReader fs = new StreamReader(filePath))
- {
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading config file: '{0}'", filePath);
-
- if (localConfigFound)
- {
- ConfigObject = JObject.Parse(fs.ReadToEnd()).ToObject();
-
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Local Config");
-
- return true;
- }
- else
- {
- var doubleObj = JObject.Parse(fs.ReadToEnd());
- ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject();
-
- // Extract SystemUrl and TemplateUrl into final config output
-
- if (doubleObj["system_url"] != null)
- {
- ConfigObject.SystemUrl = doubleObj["system_url"].Value();
- }
-
- if (doubleObj["template_url"] != null)
- {
- ConfigObject.TemplateUrl = doubleObj["template_url"].Value();
- }
- }
-
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Merged Config");
-
- return true;
- }
- }
- catch (Exception e)
- {
- Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e);
- return false;
- }
- }
-
- ///
- /// Returns all the files from the directory specified.
- ///
- ///
- ///
- public static FileInfo[] GetConfigFiles(string filePath)
- {
- // Get the directory
- var dir = Path.GetDirectoryName(filePath);
-
- if (Directory.Exists(dir))
- {
- Debug.Console(1, "Searching in Directory '{0}'", dir);
- // Get the directory info
- var dirInfo = new DirectoryInfo(dir);
-
- // Get the file name
- var fileName = Path.GetFileName(filePath);
- Debug.Console(1, "For Config Files matching: '{0}'", fileName);
-
- // Get the files that match from the directory
- return dirInfo.GetFiles(fileName);
- }
- else
- {
- Debug.Console(0, Debug.ErrorLogLevel.Notice,
- "Directory not found: ", dir);
-
- return null;
- }
- }
-
- ///
- /// Returns the group for a given device key in config
- ///
- ///
- ///
- public static string GetGroupForDeviceKey(string key)
- {
- var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
- return dev == null ? null : dev.Group;
+ }
+
+ // Read the file
+ using (StreamReader fs = new StreamReader(filePath))
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading config file: '{0}'", filePath);
+
+ if (localConfigFound)
+ {
+ ConfigObject = JObject.Parse(fs.ReadToEnd()).ToObject();
+
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Local Config");
+
+ return true;
+ }
+ else
+ {
+ var doubleObj = JObject.Parse(fs.ReadToEnd());
+ ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject();
+
+ // Extract SystemUrl and TemplateUrl into final config output
+
+ if (doubleObj["system_url"] != null)
+ {
+ ConfigObject.SystemUrl = doubleObj["system_url"].Value();
+ }
+
+ if (doubleObj["template_url"] != null)
+ {
+ ConfigObject.TemplateUrl = doubleObj["template_url"].Value();
+ }
+ }
+
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Merged Config");
+
+ return true;
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e);
+ return false;
+ }
+ }
+
+ ///
+ /// Returns all the files from the directory specified.
+ ///
+ ///
+ ///
+ public static FileInfo[] GetConfigFiles(string filePath)
+ {
+ // Get the directory
+ var dir = Path.GetDirectoryName(filePath);
+
+ if (Directory.Exists(dir))
+ {
+ Debug.Console(1, "Searching in Directory '{0}'", dir);
+ // Get the directory info
+ var dirInfo = new DirectoryInfo(dir);
+
+ // Get the file name
+ var fileName = Path.GetFileName(filePath);
+ Debug.Console(1, "For Config Files matching: '{0}'", fileName);
+
+ // Get the files that match from the directory
+ return dirInfo.GetFiles(fileName);
+ }
+ else
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Notice,
+ "Directory not found: ", dir);
+
+ return null;
+ }
+ }
+
+ ///
+ /// Returns the group for a given device key in config
+ ///
+ ///
+ ///
+ public static string GetGroupForDeviceKey(string key)
+ {
+ var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
+ return dev == null ? null : dev.Group;
}
private static void GetLocalFileMessage(string filePath)
@@ -248,7 +248,7 @@ namespace PepperDash.Essentials.Core.Config
Debug.Console(2, Debug.ErrorLogLevel.Notice, "Found Local config file: '{0}'", filePath);
Debug.Console(0, newDebugString.ToString());
- }
-
- }
+ }
+
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/INumeric.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/INumeric.cs
index 0294a0b5..62ea8b3f 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/INumeric.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/INumeric.cs
@@ -1,5 +1,5 @@
using Crestron.SimplSharpPro.DeviceSupport;
-
+using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
@@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core
///
///
///
- public interface INumericKeypad
+ public interface INumericKeypad:IKeyed
{
void Digit0(bool pressRelease);
void Digit1(bool pressRelease);
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ITvPresetsProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ITvPresetsProvider.cs
new file mode 100644
index 00000000..61b8ec09
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ITvPresetsProvider.cs
@@ -0,0 +1,9 @@
+using PepperDash.Essentials.Core.Presets;
+
+namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
+{
+ public interface ITvPresetsProvider
+ {
+ DevicePresetsModel TvPresets { get; }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs
index c7bc7c68..51d5882f 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs
@@ -83,13 +83,13 @@ namespace PepperDash.Essentials.Core
///
public static object GetPropertyByName(string deviceObjectPath, string propertyName)
{
- var obj = FindObjectOnPath(deviceObjectPath);
- if(obj == null)
+ var dev = FindObjectOnPath(deviceObjectPath);
+ if(dev == null)
return "{ \"error\":\"No Device\"}";
+
+ object prop = dev.GetType().GetCType().GetProperty(propertyName).GetValue(dev, null);
- CType t = obj.GetType();
-
- var prop = t.GetProperty(propertyName);
+ // var prop = t.GetProperty(propertyName);
if (prop != null)
{
return prop;
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs
index 0e4efa10..55bc523a 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs
@@ -360,9 +360,9 @@ namespace PepperDash.Essentials.Core
{
var device = GetDeviceForKey(s);
- if (device == null) return;
- var inputPorts = (device as IRoutingInputsOutputs).InputPorts;
- var outputPorts = (device as IRoutingInputsOutputs).OutputPorts;
+ if (device == null) return;
+ var inputPorts = ((device as IRoutingInputs) != null) ? (device as IRoutingInputs).InputPorts : null;
+ var outputPorts = ((device as IRoutingOutputs) != null) ? (device as IRoutingOutputs).OutputPorts : null;
if (inputPorts != null)
{
Debug.Console(0, "Device {0} has {1} Input Ports:", s, inputPorts.Count);
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs
index 8d70bd55..3c691c19 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs
@@ -20,7 +20,8 @@ namespace PepperDash.Essentials.Core
public IrOutputPortController IrPort { get; private set; }
public ushort IrPulseTime { get; set; }
- public BoolFeedback PowerIsOnFeedback { get; private set; }
+ [Obsolete("This property will be removed in version 2.0.0")]
+ public override BoolFeedback PowerIsOnFeedback { get; protected set; }
protected Func PowerIsOnFeedbackFunc
{
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs
index e4a2cb26..17ff8bd1 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs
@@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Core
///
///
///
- public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking
+ public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IPower
{
public event SourceInfoChangeHandler CurrentSourceChange;
@@ -49,6 +49,9 @@ namespace PepperDash.Essentials.Core
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
public BoolFeedback IsWarmingUpFeedback { get; private set; }
+ [Obsolete("This property will be removed in version 2.0.0")]
+ public abstract BoolFeedback PowerIsOnFeedback { get; protected set; }
+
public UsageTracking UsageTracker { get; set; }
public uint WarmupTime { get; set; }
@@ -81,8 +84,6 @@ namespace PepperDash.Essentials.Core
}
-
-
public abstract void PowerOn();
public abstract void PowerOff();
public abstract void PowerToggle();
@@ -99,7 +100,7 @@ namespace PepperDash.Essentials.Core
}
}
- public abstract void ExecuteSwitch(object selector);
+ public abstract void ExecuteSwitch(object selector);
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
EiscApiAdvanced bridge)
@@ -261,7 +262,8 @@ namespace PepperDash.Essentials.Core
abstract protected Func CurrentInputFeedbackFunc { get; }
- public BoolFeedback PowerIsOnFeedback { get; protected set; }
+ public override BoolFeedback PowerIsOnFeedback { get; protected set; }
+
abstract protected Func PowerIsOnFeedbackFunc { get; }
@@ -315,7 +317,5 @@ namespace PepperDash.Essentials.Core
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
-
-
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs
index 39cd7d78..9574743e 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs
@@ -2,164 +2,133 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
-
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.CrestronXml;
using Crestron.SimplSharp.CrestronXml.Serialization;
-using Crestron.SimplSharp.CrestronXmlLinq;
using Crestron.SimplSharpPro;
-using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.Fusion;
using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-
using PepperDash.Core;
-using PepperDash.Essentials;
-using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
-
-
namespace PepperDash.Essentials.Core.Fusion
{
- public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider
- {
- public event EventHandler ScheduleChange;
- //public event EventHandler MeetingEndWarning;
- //public event EventHandler NextMeetingBeginWarning;
+ public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider
+ {
+ protected EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap;
- public event EventHandler RoomInfoChange;
+ private const string RemoteOccupancyXml = "Local{0}";
+ private readonly bool _guidFileExists;
+
+ private readonly Dictionary _sourceToFeedbackSigs =
+ new Dictionary();
+
+ protected StringSigData CurrentRoomSourceNameSig;
public FusionCustomPropertiesBridge CustomPropertiesBridge = new FusionCustomPropertiesBridge();
+ protected FusionOccupancySensorAsset FusionOccSensor;
+ protected FusionRemoteOccupancySensor FusionRemoteOccSensor;
- protected FusionRoom FusionRoom;
- protected EssentialsRoomBase Room;
- Dictionary SourceToFeedbackSigs =
- new Dictionary();
+ protected FusionRoom FusionRoom;
+ protected Dictionary FusionStaticAssets;
+ public long PushNotificationTimeout = 5000;
+ protected EssentialsRoomBase Room;
+ public long SchedulePollInterval = 300000;
- StatusMonitorCollection ErrorMessageRollUp;
+ private Event _currentMeeting;
+ private RoomSchedule _currentSchedule;
+ private CTimer _dailyTimeRequestTimer;
+ private StatusMonitorCollection _errorMessageRollUp;
- protected StringSigData CurrentRoomSourceNameSig;
+ private FusionRoomGuids _guiDs;
+ private uint _ipId;
+
+ private bool _isRegisteredForSchedulePushNotifications;
+ private Event _nextMeeting;
+
+ private CTimer _pollTimer;
+
+ private CTimer _pushNotificationTimer;
+
+ private string _roomOccupancyRemoteString;
#region System Info Sigs
+
//StringSigData SystemName;
//StringSigData Model;
//StringSigData SerialNumber;
//StringSigData Uptime;
+
#endregion
-
#region Processor Info Sigs
- StringSigData Ip1;
- StringSigData Ip2;
- StringSigData Gateway;
- StringSigData Hostname;
- StringSigData Domain;
- StringSigData Dns1;
- StringSigData Dns2;
- StringSigData Mac1;
- StringSigData Mac2;
- StringSigData NetMask1;
- StringSigData NetMask2;
- StringSigData Firmware;
- StringSigData[] Program = new StringSigData[10];
+ private readonly StringSigData[] _program = new StringSigData[10];
+ private StringSigData _dns1;
+ private StringSigData _dns2;
+ private StringSigData _domain;
+ private StringSigData _firmware;
+ private StringSigData _gateway;
+ private StringSigData _hostname;
+ private StringSigData _ip1;
+ private StringSigData _ip2;
+ private StringSigData _mac1;
+ private StringSigData _mac2;
+ private StringSigData _netMask1;
+ private StringSigData _netMask2;
+
#endregion
#region Default Display Source Sigs
- BooleanSigData[] Source = new BooleanSigData[10];
+ private BooleanSigData[] _source = new BooleanSigData[10];
#endregion
- RoomSchedule CurrentSchedule;
-
- Event NextMeeting;
-
- Event CurrentMeeting;
-
- protected string RoomGuid
+ public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId, string joinMapKey)
+ : base(room.Key + "-fusion")
{
- get
- {
- return GUIDs.RoomGuid;
- }
-
- }
-
- uint IpId;
-
- FusionRoomGuids GUIDs;
-
- bool GuidFileExists;
-
- bool IsRegisteredForSchedulePushNotifications = false;
-
- CTimer PollTimer = null;
-
- CTimer PushNotificationTimer = null;
-
- CTimer DailyTimeRequestTimer = null;
-
- // Default poll time is 5 min unless overridden by config value
- public long SchedulePollInterval = 300000;
-
- public long PushNotificationTimeout = 5000;
-
- private const string RemoteOccupancyXml = "Local{0}";
-
- protected Dictionary FusionStaticAssets;
-
- // For use with local occ sensor devices which will relay to Fusion the current occupancy status
- protected FusionRemoteOccupancySensor FusionRemoteOccSensor;
-
- // For use with occ sensor attached to a scheduling panel in Fusion
- protected FusionOccupancySensorAsset FusionOccSensor;
-
- public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
-
- private string _roomOccupancyRemoteString;
- public StringFeedback RoomOccupancyRemoteStringFeedback { get; private set; }
-
- protected Func RoomIsOccupiedFeedbackFunc
- {
- get
- {
- return () => FusionRemoteOccSensor.RoomOccupied.OutputSig.BoolValue;
- }
- }
-
- //ScheduleResponseEvent NextMeeting;
-
- public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId)
- : base(room.Key + "-fusion")
- {
-
try
{
+ JoinMap = new EssentialsHuddleSpaceRoomFusionRoomJoinMap(1);
+ CrestronConsole.AddNewConsoleCommand((o) => JoinMap.PrintJoinMapInfo(), string.Format("ptjnmp-{0}", Key), "Prints Attribute Join Map", ConsoleAccessLevelEnum.AccessOperator);
+
+ if (!string.IsNullOrEmpty(joinMapKey))
+ {
+ var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
+ if (customJoins != null)
+ {
+ JoinMap.SetCustomJoinData(customJoins);
+ }
+ }
+
Room = room;
- IpId = ipId;
+ _ipId = ipId;
FusionStaticAssets = new Dictionary();
- GUIDs = new FusionRoomGuids();
+ _guiDs = new FusionRoomGuids();
- var mac = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0);
+ var mac =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0);
var slot = Global.ControlSystem.ProgramNumber;
- string guidFilePath = Global.FilePathPrefix + string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
+ var guidFilePath = Global.FilePathPrefix +
+ string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
- GuidFileExists = File.Exists(guidFilePath);
+ _guidFileExists = File.Exists(guidFilePath);
// Check if file exists
- if (!GuidFileExists)
+ if (!_guidFileExists)
{
// Does not exist. Create GUIDs
- GUIDs = new FusionRoomGuids(Room.Name, ipId, GUIDs.GenerateNewRoomGuid(slot, mac), FusionStaticAssets);
+ _guiDs = new FusionRoomGuids(Room.Name, ipId, _guiDs.GenerateNewRoomGuid(slot, mac),
+ FusionStaticAssets);
}
else
{
@@ -170,18 +139,19 @@ namespace PepperDash.Essentials.Core.Fusion
if (Room.RoomOccupancy != null)
{
if (Room.OccupancyStatusProviderIsRemote)
+ {
SetUpRemoteOccupancy();
+ }
else
{
SetUpLocalOccupancy();
}
}
-
AddPostActivationAction(() =>
{
- CreateSymbolAndBasicSigs(IpId);
+ CreateSymbolAndBasicSigs(_ipId);
SetUpSources();
SetUpCommunitcationMonitors();
SetUpDisplay();
@@ -192,27 +162,51 @@ namespace PepperDash.Essentials.Core.Fusion
GenerateGuidFile(guidFilePath);
});
-
}
catch (Exception e)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error Building Fusion System Controller: {0}", e);
}
- }
+ }
+
+ protected string RoomGuid
+ {
+ get { return _guiDs.RoomGuid; }
+ }
+
+ public StringFeedback RoomOccupancyRemoteStringFeedback { get; private set; }
+
+ protected Func RoomIsOccupiedFeedbackFunc
+ {
+ get { return () => FusionRemoteOccSensor.RoomOccupied.OutputSig.BoolValue; }
+ }
+
+ #region IOccupancyStatusProvider Members
+
+ public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
+
+ #endregion
+
+ public event EventHandler ScheduleChange;
+ //public event EventHandler MeetingEndWarning;
+ //public event EventHandler NextMeetingBeginWarning;
+
+ public event EventHandler RoomInfoChange;
+
+ //ScheduleResponseEvent NextMeeting;
///
/// Used for extension classes to execute whatever steps are necessary before generating the RVI and GUID files
///
protected virtual void ExecuteCustomSteps()
{
-
}
///
/// Generates the guid file in NVRAM. If the file already exists it will be overwritten.
///
/// path for the file
- void GenerateGuidFile(string filePath)
+ private void GenerateGuidFile(string filePath)
{
if (string.IsNullOrEmpty(filePath))
{
@@ -220,32 +214,32 @@ namespace PepperDash.Essentials.Core.Fusion
return;
}
- CCriticalSection _fileLock = new CCriticalSection();
+ var fileLock = new CCriticalSection();
try
{
- if (_fileLock == null || _fileLock.Disposed)
+ if (fileLock.Disposed)
+ {
return;
+ }
- _fileLock.Enter();
+ fileLock.Enter();
Debug.Console(1, this, "Writing GUIDs to file");
- if (FusionOccSensor == null)
- GUIDs = new FusionRoomGuids(Room.Name, IpId, RoomGuid, FusionStaticAssets);
- else
- GUIDs = new FusionRoomGuids(Room.Name, IpId, RoomGuid, FusionStaticAssets, FusionOccSensor);
+ _guiDs = FusionOccSensor == null
+ ? new FusionRoomGuids(Room.Name, _ipId, RoomGuid, FusionStaticAssets)
+ : new FusionRoomGuids(Room.Name, _ipId, RoomGuid, FusionStaticAssets, FusionOccSensor);
- var JSON = JsonConvert.SerializeObject(GUIDs, Newtonsoft.Json.Formatting.Indented);
+ var json = JsonConvert.SerializeObject(_guiDs, Newtonsoft.Json.Formatting.Indented);
- using (StreamWriter sw = new StreamWriter(filePath))
+ using (var sw = new StreamWriter(filePath))
{
- sw.Write(JSON);
+ sw.Write(json);
sw.Flush();
}
Debug.Console(1, this, "Guids successfully written to file '{0}'", filePath);
-
}
catch (Exception e)
{
@@ -253,8 +247,10 @@ namespace PepperDash.Essentials.Core.Fusion
}
finally
{
- if (_fileLock != null && !_fileLock.Disposed)
- _fileLock.Leave();
+ if (!fileLock.Disposed)
+ {
+ fileLock.Leave();
+ }
}
}
@@ -262,42 +258,45 @@ namespace PepperDash.Essentials.Core.Fusion
/// Reads the guid file from NVRAM
///
/// path for te file
- void ReadGuidFile(string filePath)
+ private void ReadGuidFile(string filePath)
{
- if(string.IsNullOrEmpty(filePath))
+ if (string.IsNullOrEmpty(filePath))
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Error reading guid file. No path specified.");
return;
}
- CCriticalSection _fileLock = new CCriticalSection();
+ var fileLock = new CCriticalSection();
try
{
- if(_fileLock == null || _fileLock.Disposed)
- return;
-
- _fileLock.Enter();
-
- if(File.Exists(filePath))
+ if (fileLock.Disposed)
{
- var JSON = File.ReadToEnd(filePath, Encoding.ASCII);
-
- GUIDs = JsonConvert.DeserializeObject(JSON);
-
- IpId = GUIDs.IpId;
-
- FusionStaticAssets = GUIDs.StaticAssets;
-
+ return;
}
- Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Fusion Guids successfully read from file: {0}", filePath);
+ fileLock.Enter();
- Debug.Console(1, this, "\nRoom Name: {0}\nIPID: {1:x}\n RoomGuid: {2}", Room.Name, IpId, RoomGuid);
+ if (File.Exists(filePath))
+ {
+ var json = File.ReadToEnd(filePath, Encoding.ASCII);
+
+ _guiDs = JsonConvert.DeserializeObject(json);
+
+ _ipId = _guiDs.IpId;
+
+ FusionStaticAssets = _guiDs.StaticAssets;
+ }
+
+ Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Fusion Guids successfully read from file: {0}",
+ filePath);
+
+ Debug.Console(1, this, "\r\n********************\r\n\tRoom Name: {0}\r\n\tIPID: {1:X}\r\n\tRoomGuid: {2}\r\n*******************", Room.Name, _ipId, RoomGuid);
foreach (var item in FusionStaticAssets)
{
- Debug.Console(1, this, "\nAsset Name: {0}\nAsset No: {1}\n Guid: {2}", item.Value.Name, item.Value.SlotNumber, item.Value.InstanceId);
+ Debug.Console(1, this, "\nAsset Name: {0}\nAsset No: {1}\n Guid: {2}", item.Value.Name,
+ item.Value.SlotNumber, item.Value.InstanceId);
}
}
catch (Exception e)
@@ -306,46 +305,65 @@ namespace PepperDash.Essentials.Core.Fusion
}
finally
{
- if(_fileLock != null && !_fileLock.Disposed)
- _fileLock.Leave();
+ if (!fileLock.Disposed)
+ {
+ fileLock.Leave();
+ }
}
-
}
- protected virtual void CreateSymbolAndBasicSigs(uint ipId)
- {
+ protected virtual void CreateSymbolAndBasicSigs(uint ipId)
+ {
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "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.Register();
- FusionRoom.FusionStateChange += new FusionStateEventHandler(FusionRoom_FusionStateChange);
+ FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
- FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += new DeviceExtenderJoinChangeEventHandler(FusionRoomSchedule_DeviceExtenderSigChange);
- FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += new DeviceExtenderJoinChangeEventHandler(ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange);
- FusionRoom.OnlineStatusChange += new OnlineStatusChangeEventHandler(FusionRoom_OnlineStatusChange);
+ 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);
+ 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(CreateAdHocMeeting, "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);
+ // 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 IHasCurrentSourceInfoChange).CurrentSourceChange += new SourceInfoChangeHandler(Room_CurrentSourceInfoChange);
+ CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName,
+ eSigIoMask.InputSigOnly);
+ // Don't think we need to get current status of this as nothing should be alive yet.
+ var hasCurrentSourceInfoChange = Room as IHasCurrentSourceInfoChange;
+ if (hasCurrentSourceInfoChange != null)
+ {
+ hasCurrentSourceInfoChange.CurrentSourceChange += Room_CurrentSourceInfoChange;
+ }
- FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsRoomBase).PowerOnToDefaultOrLastSource);
- FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IRunRouteAction).RunRouteAction("roomOff", Room.SourceListKey));
- // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
- FusionRoom.ErrorMessage.InputSig.StringValue =
- "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;";
+ FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(Room.PowerOnToDefaultOrLastSource);
+ FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() =>
+ {
+ var runRouteAction = Room as IRunRouteAction;
+ if (runRouteAction != null)
+ {
+ runRouteAction.RunRouteAction("roomOff", Room.SourceListKey);
+ }
+ });
+ // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
+ FusionRoom.ErrorMessage.InputSig.StringValue =
+ "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;";
SetUpEthernetValues();
@@ -355,7 +373,7 @@ namespace PepperDash.Essentials.Core.Fusion
GetProcessorInfo();
- CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
+ CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
}
protected void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs)
@@ -372,82 +390,107 @@ namespace PepperDash.Essentials.Core.Fusion
//Model.InputSig.StringValue = InitialParametersClass.ControllerPromptName;
//SerialNumber.InputSig.StringValue = InitialParametersClass.
- string response = string.Empty;
+ var response = string.Empty;
- var systemReboot = FusionRoom.CreateOffsetBoolSig(74, "Processor - Reboot", eSigIoMask.OutputSigOnly);
- systemReboot.OutputSig.SetSigFalseAction(() => CrestronConsole.SendControlSystemCommand("reboot", ref response));
+ var systemReboot = FusionRoom.CreateOffsetBoolSig(JoinMap.ProcessorReboot.JoinNumber, JoinMap.ProcessorReboot.AttributeName, eSigIoMask.OutputSigOnly);
+ systemReboot.OutputSig.SetSigFalseAction(
+ () => CrestronConsole.SendControlSystemCommand("reboot", ref response));
}
protected void SetUpEthernetValues()
{
- Ip1 = FusionRoom.CreateOffsetStringSig(50, "Info - Processor - IP 1", eSigIoMask.InputSigOnly);
- Ip2 = FusionRoom.CreateOffsetStringSig(51, "Info - Processor - IP 2", eSigIoMask.InputSigOnly);
- Gateway = FusionRoom.CreateOffsetStringSig(52, "Info - Processor - Gateway", eSigIoMask.InputSigOnly);
- Hostname = FusionRoom.CreateOffsetStringSig(53, "Info - Processor - Hostname", eSigIoMask.InputSigOnly);
- Domain = FusionRoom.CreateOffsetStringSig(54, "Info - Processor - Domain", eSigIoMask.InputSigOnly);
- Dns1 = FusionRoom.CreateOffsetStringSig(55, "Info - Processor - DNS 1", eSigIoMask.InputSigOnly);
- Dns2 = FusionRoom.CreateOffsetStringSig(56, "Info - Processor - DNS 2", eSigIoMask.InputSigOnly);
- Mac1 = FusionRoom.CreateOffsetStringSig(57, "Info - Processor - MAC 1", eSigIoMask.InputSigOnly);
- Mac2 = FusionRoom.CreateOffsetStringSig(58, "Info - Processor - MAC 2", eSigIoMask.InputSigOnly);
- NetMask1 = FusionRoom.CreateOffsetStringSig(59, "Info - Processor - Net Mask 1", eSigIoMask.InputSigOnly);
- NetMask2 = FusionRoom.CreateOffsetStringSig(60, "Info - Processor - Net Mask 2", eSigIoMask.InputSigOnly);
+ _ip1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp1.JoinNumber, JoinMap.ProcessorIp1.AttributeName, eSigIoMask.InputSigOnly);
+ _ip2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp2.JoinNumber, JoinMap.ProcessorIp2.AttributeName, eSigIoMask.InputSigOnly);
+ _gateway = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorGateway.JoinNumber, JoinMap.ProcessorGateway.AttributeName, eSigIoMask.InputSigOnly);
+ _hostname = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorHostname.JoinNumber, JoinMap.ProcessorHostname.AttributeName, eSigIoMask.InputSigOnly);
+ _domain = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDomain.JoinNumber, JoinMap.ProcessorDomain.AttributeName, eSigIoMask.InputSigOnly);
+ _dns1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns1.JoinNumber, JoinMap.ProcessorDns1.AttributeName, eSigIoMask.InputSigOnly);
+ _dns2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns2.JoinNumber, JoinMap.ProcessorDns2.AttributeName, eSigIoMask.InputSigOnly);
+ _mac1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac1.JoinNumber, JoinMap.ProcessorMac1.AttributeName, eSigIoMask.InputSigOnly);
+ _mac2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac2.JoinNumber, JoinMap.ProcessorMac2.AttributeName, eSigIoMask.InputSigOnly);
+ _netMask1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask1.JoinNumber, JoinMap.ProcessorNetMask1.AttributeName, eSigIoMask.InputSigOnly);
+ _netMask2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask2.JoinNumber, JoinMap.ProcessorNetMask2.AttributeName, eSigIoMask.InputSigOnly);
}
protected void GetProcessorEthernetValues()
{
- Ip1.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
- Gateway.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, 0);
- Hostname.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
- Domain.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, 0);
+ _ip1.InputSig.StringValue =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
+ _gateway.InputSig.StringValue =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, 0);
+ _hostname.InputSig.StringValue =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
+ _domain.InputSig.StringValue =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, 0);
- var dnsServers = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, 0).Split(',');
- Dns1.InputSig.StringValue = dnsServers[0];
+ var dnsServers =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, 0).Split(',');
+ _dns1.InputSig.StringValue = dnsServers[0];
if (dnsServers.Length > 1)
- Dns2.InputSig.StringValue = dnsServers[1];
+ {
+ _dns2.InputSig.StringValue = dnsServers[1];
+ }
- Mac1.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0);
- NetMask1.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 0);
+ _mac1.InputSig.StringValue =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0);
+ _netMask1.InputSig.StringValue =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 0);
// Interface 1
- if (InitialParametersClass.NumberOfEthernetInterfaces > 1) // Only get these values if the processor has more than 1 NIC
+ if (InitialParametersClass.NumberOfEthernetInterfaces > 1)
+ // Only get these values if the processor has more than 1 NIC
{
- Ip2.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 1);
- Mac2.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 1);
- NetMask2.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 1);
+ _ip2.InputSig.StringValue =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 1);
+ _mac2.InputSig.StringValue =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 1);
+ _netMask2.InputSig.StringValue =
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 1);
}
}
protected void GetProcessorInfo()
{
-
- Firmware = FusionRoom.CreateOffsetStringSig(61, "Info - Processor - Firmware", eSigIoMask.InputSigOnly);
+ _firmware = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorFirmware.JoinNumber, JoinMap.ProcessorFirmware.AttributeName, eSigIoMask.InputSigOnly);
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server)
{
- for (int i = 0; i < Global.ControlSystem.NumProgramsSupported; i++)
+ for (var i = 0; i < Global.ControlSystem.NumProgramsSupported; i++)
{
- var join = 62 + i;
+ var join = JoinMap.ProgramNameStart.JoinNumber + i;
var progNum = i + 1;
- Program[i] = FusionRoom.CreateOffsetStringSig((uint)join, string.Format("Info - Processor - Program {0}", progNum), eSigIoMask.InputSigOnly);
+ _program[i] = FusionRoom.CreateOffsetStringSig((uint) join,
+ string.Format("{0} {1}", JoinMap.ProgramNameStart.AttributeName, progNum), eSigIoMask.InputSigOnly);
}
}
- Firmware.InputSig.StringValue = InitialParametersClass.FirmwareVersion;
-
+ _firmware.InputSig.StringValue = InitialParametersClass.FirmwareVersion;
}
protected void GetCustomProperties()
{
if (FusionRoom.IsOnline)
{
- string fusionRoomCustomPropertiesRequest = @"RoomConfigurationRequest";
+ const string fusionRoomCustomPropertiesRequest =
+ @"RoomConfigurationRequest";
- FusionRoom.ExtenderFusionRoomDataReservedSigs.RoomConfigQuery.StringValue = fusionRoomCustomPropertiesRequest;
+ FusionRoom.ExtenderFusionRoomDataReservedSigs.RoomConfigQuery.StringValue =
+ fusionRoomCustomPropertiesRequest;
}
}
- void GetTouchpanelInfo()
+ private void GetTouchpanelInfo()
{
// TODO: Get IP and Project Name from TP
}
@@ -456,17 +499,19 @@ namespace PepperDash.Essentials.Core.Fusion
{
if (args.DeviceOnLine)
{
- CrestronEnvironment.Sleep(200);
+ CrestronInvoke.BeginInvoke( (o) =>
+ {
+ CrestronEnvironment.Sleep(200);
- // Send Push Notification Action request:
+ // Send Push Notification Action request:
- string requestID = "InitialPushRequest";
+ const string requestId = "InitialPushRequest";
- string actionRequest =
- string.Format("\n{0}\n", requestID) +
- "RegisterPushModel\n" +
- "\n" +
+ var actionRequest =
+ string.Format("\n{0}\n", requestId) +
+ "RegisterPushModel\n" +
+ "\n" +
"\n" +
"\n" +
"\n" +
@@ -485,30 +530,30 @@ namespace PepperDash.Essentials.Core.Fusion
"\n" +
"\n" +
"\n" +
- "\n" +
- "\n";
+ "\n" +
+ "\n";
- Debug.Console(2, this, "Sending Fusion ActionRequest: \n{0}", actionRequest);
+ Debug.Console(2, this, "Sending Fusion ActionRequest: \n{0}", actionRequest);
- FusionRoom.ExtenderFusionRoomDataReservedSigs.ActionQuery.StringValue = actionRequest;
+ FusionRoom.ExtenderFusionRoomDataReservedSigs.ActionQuery.StringValue = actionRequest;
- GetCustomProperties();
+ GetCustomProperties();
- // Request current Fusion Server Time
- RequestLocalDateTime(null);
+ // Request current Fusion Server Time
+ RequestLocalDateTime(null);
- // Setup timer to request time daily
- if (DailyTimeRequestTimer != null && !DailyTimeRequestTimer.Disposed)
- {
- DailyTimeRequestTimer.Stop();
- DailyTimeRequestTimer.Dispose();
- }
+ // Setup timer to request time daily
+ if (_dailyTimeRequestTimer != null && !_dailyTimeRequestTimer.Disposed)
+ {
+ _dailyTimeRequestTimer.Stop();
+ _dailyTimeRequestTimer.Dispose();
+ }
- DailyTimeRequestTimer = new CTimer(RequestLocalDateTime, null, 86400000, 86400000);
+ _dailyTimeRequestTimer = new CTimer(RequestLocalDateTime, null, 86400000, 86400000);
- DailyTimeRequestTimer.Reset(86400000, 86400000);
+ _dailyTimeRequestTimer.Reset(86400000, 86400000);
+ });
}
-
}
///
@@ -517,9 +562,10 @@ namespace PepperDash.Essentials.Core.Fusion
///
public void RequestLocalDateTime(object callbackObject)
{
- string timeRequestID = "TimeRequest";
+ const string timeRequestId = "TimeRequest";
- string timeRequest = string.Format("{0}", timeRequestID);
+ var timeRequest = string.Format("{0}",
+ timeRequestId);
FusionRoom.ExtenderFusionRoomDataReservedSigs.LocalDateTimeQuery.StringValue = timeRequest;
}
@@ -527,79 +573,78 @@ namespace PepperDash.Essentials.Core.Fusion
///
/// Generates a room schedule request for this room for the next 24 hours.
///
- /// string identifying this request. Used with a corresponding ScheduleResponse value
public void RequestFullRoomSchedule(object callbackObject)
{
- DateTime now = DateTime.Today;
+ var now = DateTime.Today;
- string currentTime = now.ToString("s");
+ var currentTime = now.ToString("s");
- string requestTest =
- string.Format("FullSchedleRequest{0}{1}24", RoomGuid, currentTime);
+ var requestTest =
+ string.Format(
+ "FullSchedleRequest{0}{1}24",
+ RoomGuid, currentTime);
Debug.Console(2, this, "Sending Fusion ScheduleQuery: \n{0}", requestTest);
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.ScheduleQuery.StringValue = requestTest;
- if (IsRegisteredForSchedulePushNotifications)
- PushNotificationTimer.Stop();
+ if (_isRegisteredForSchedulePushNotifications)
+ {
+ _pushNotificationTimer.Stop();
+ }
}
-
+
///
/// Wrapper method to allow console commands to modify the current meeting end time
///
/// meetingID extendTime
public void ModifyMeetingEndTimeConsoleHelper(string command)
{
- string requestID;
- string meetingID = null;
- int extendMinutes = -1;
+ var extendMinutes = -1;
- requestID = "ModifyMeetingTest12345";
+ const string requestId = "ModifyMeetingTest12345";
try
{
var tokens = command.Split(' ');
- meetingID = tokens[0];
extendMinutes = Int32.Parse(tokens[1]);
-
}
catch (Exception e)
{
Debug.Console(1, this, "Error parsing console command: {0}", e);
}
- ModifyMeetingEndTime(requestID, extendMinutes);
-
+ ModifyMeetingEndTime(requestId, extendMinutes);
}
///
/// Ends or Extends the current meeting by the specified number of minutes.
///
+ ///
/// Number of minutes to extend the meeting. A value of 0 will end the meeting.
- public void ModifyMeetingEndTime(string requestID, int extendMinutes)
+ public void ModifyMeetingEndTime(string requestId, int extendMinutes)
{
- if(CurrentMeeting == null)
+ if (_currentMeeting == null)
{
Debug.Console(1, this, "No meeting in progress. Unable to modify end time.");
return;
- }
+ }
if (extendMinutes > -1)
{
- if(extendMinutes > 0)
+ if (extendMinutes > 0)
{
- var extendTime = CurrentMeeting.dtEnd - DateTime.Now;
- double extendMinutesRaw = extendTime.TotalMinutes;
+ var extendTime = _currentMeeting.dtEnd - DateTime.Now;
+ var extendMinutesRaw = extendTime.TotalMinutes;
- extendMinutes = extendMinutes + (int)Math.Round(extendMinutesRaw);
+ extendMinutes = extendMinutes + (int) Math.Round(extendMinutesRaw);
}
- string requestTest = string.Format(
+ var requestTest = string.Format(
"{0}{1}MeetingChange"
- , requestID, RoomGuid, CurrentMeeting.MeetingID, extendMinutes);
+ , requestId, RoomGuid, _currentMeeting.MeetingID, extendMinutes);
Debug.Console(1, this, "Sending MeetingChange Request: \n{0}", requestTest);
@@ -609,47 +654,45 @@ namespace PepperDash.Essentials.Core.Fusion
{
Debug.Console(1, this, "Invalid time specified");
}
-
-
}
///
/// Creates and Ad Hoc meeting with a duration of 1 hour, or until the next meeting if in less than 1 hour.
///
- public void CreateAsHocMeeting(string command)
+ public void CreateAdHocMeeting(string command)
{
- string requestID = "CreateAdHocMeeting";
+ const string requestId = "CreateAdHocMeeting";
- DateTime now = DateTime.Now.AddMinutes(1);
+ var now = DateTime.Now.AddMinutes(1);
now.AddSeconds(-now.Second);
// Assume 1 hour meeting if possible
- DateTime dtEnd = now.AddHours(1);
+ var dtEnd = now.AddHours(1);
// Check if room is available for 1 hour before next meeting
- if (NextMeeting != null)
+ if (_nextMeeting != null)
{
- var roomAvailable = NextMeeting.dtEnd.Subtract(dtEnd);
+ var roomAvailable = _nextMeeting.dtEnd.Subtract(dtEnd);
if (roomAvailable.TotalMinutes < 60)
{
- /// Room not available for full hour, book until next meeting starts
- dtEnd = NextMeeting.dtEnd;
+ // Room not available for full hour, book until next meeting starts
+ dtEnd = _nextMeeting.dtEnd;
}
}
- string createMeetingRequest =
+ var createMeetingRequest =
"" +
- string.Format("{0}", requestID) +
- string.Format("{0}", RoomGuid) +
- "" +
- string.Format("{0}", now.ToString("s")) +
- string.Format("{0}", dtEnd.ToString("s")) +
- "AdHoc Meeting" +
- "Room User" +
- "Example Message" +
- "" +
+ string.Format("{0}", requestId) +
+ string.Format("{0}", RoomGuid) +
+ "" +
+ string.Format("{0}", now.ToString("s")) +
+ string.Format("{0}", dtEnd.ToString("s")) +
+ "AdHoc Meeting" +
+ "Room User" +
+ "Example Message" +
+ "" +
"";
Debug.Console(2, this, "Sending CreateMeeting Request: \n{0}", createMeetingRequest);
@@ -659,7 +702,6 @@ namespace PepperDash.Essentials.Core.Fusion
//Debug.Console(1, this, "Sending CreateMeeting Request: \n{0}", command);
//FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.CreateMeeting.StringValue = command;
-
}
///
@@ -667,73 +709,73 @@ namespace PepperDash.Essentials.Core.Fusion
///
///
///
- protected void ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
+ protected void ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender,
+ SigEventArgs args)
{
- Debug.Console(2, this, "Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue);
+ Debug.Console(2, this, "Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name,
+ args.Sig.StringValue);
if (args.Sig == FusionRoom.ExtenderFusionRoomDataReservedSigs.ActionQueryResponse)
{
try
{
- XmlDocument message = new XmlDocument();
+ var message = new XmlDocument();
message.LoadXml(args.Sig.StringValue);
var actionResponse = message["ActionResponse"];
- if (actionResponse != null)
+ if (actionResponse == null)
{
- var requestID = actionResponse["RequestID"];
+ return;
+ }
- if (requestID.InnerText == "InitialPushRequest")
+ var requestId = actionResponse["RequestID"];
+
+ if (requestId.InnerText != "InitialPushRequest")
+ {
+ return;
+ }
+
+ if (actionResponse["ActionID"].InnerText != "RegisterPushModel")
+ {
+ return;
+ }
+
+ var parameters = actionResponse["Parameters"];
+
+ foreach (var isRegistered in from XmlElement parameter in parameters
+ where parameter.HasAttributes
+ select parameter.Attributes
+ into attributes
+ where attributes["ID"].Value == "Registered"
+ select Int32.Parse(attributes["Value"].Value))
+ {
+ switch (isRegistered)
{
- if (actionResponse["ActionID"].InnerText == "RegisterPushModel")
- {
- var parameters = actionResponse["Parameters"];
-
- foreach (XmlElement parameter in parameters)
+ case 1:
+ _isRegisteredForSchedulePushNotifications = true;
+ if (_pollTimer != null && !_pollTimer.Disposed)
{
- if (parameter.HasAttributes)
- {
- var attributes = parameter.Attributes;
-
- if (attributes["ID"].Value == "Registered")
- {
- var isRegistered = Int32.Parse(attributes["Value"].Value);
-
- if (isRegistered == 1)
- {
- IsRegisteredForSchedulePushNotifications = true;
-
- if (PollTimer != null && !PollTimer.Disposed)
- {
- PollTimer.Stop();
- PollTimer.Dispose();
- }
-
- PushNotificationTimer = new CTimer(RequestFullRoomSchedule, null, PushNotificationTimeout, PushNotificationTimeout);
-
- PushNotificationTimer.Reset(PushNotificationTimeout, PushNotificationTimeout);
- }
- else if (isRegistered == 0)
- {
- IsRegisteredForSchedulePushNotifications = false;
-
- if (PushNotificationTimer != null && !PushNotificationTimer.Disposed)
- {
- PushNotificationTimer.Stop();
- PushNotificationTimer.Dispose();
- }
-
- PollTimer = new CTimer(RequestFullRoomSchedule, null, SchedulePollInterval, SchedulePollInterval);
-
- PollTimer.Reset(SchedulePollInterval, SchedulePollInterval);
- }
- }
- }
+ _pollTimer.Stop();
+ _pollTimer.Dispose();
}
- }
+ _pushNotificationTimer = new CTimer(RequestFullRoomSchedule, null,
+ PushNotificationTimeout, PushNotificationTimeout);
+ _pushNotificationTimer.Reset(PushNotificationTimeout, PushNotificationTimeout);
+ break;
+ case 0:
+ _isRegisteredForSchedulePushNotifications = false;
+ if (_pushNotificationTimer != null && !_pushNotificationTimer.Disposed)
+ {
+ _pushNotificationTimer.Stop();
+ _pushNotificationTimer.Dispose();
+ }
+ _pollTimer = new CTimer(RequestFullRoomSchedule, null, SchedulePollInterval,
+ SchedulePollInterval);
+ _pollTimer.Reset(SchedulePollInterval, SchedulePollInterval);
+ break;
}
}
}
@@ -746,7 +788,7 @@ namespace PepperDash.Essentials.Core.Fusion
{
try
{
- XmlDocument message = new XmlDocument();
+ var message = new XmlDocument();
message.LoadXml(args.Sig.StringValue);
@@ -759,13 +801,15 @@ namespace PepperDash.Essentials.Core.Fusion
if (localDateTime != null)
{
var tempLocalDateTime = localDateTime.InnerText;
-
- DateTime currentTime = DateTime.Parse(tempLocalDateTime);
+
+ var currentTime = DateTime.Parse(tempLocalDateTime);
Debug.Console(1, this, "DateTime from Fusion Server: {0}", currentTime);
// Parse time and date from response and insert values
- CrestronEnvironment.SetTimeAndDate((ushort)currentTime.Hour, (ushort)currentTime.Minute, (ushort)currentTime.Second, (ushort)currentTime.Month, (ushort)currentTime.Day, (ushort)currentTime.Year);
+ CrestronEnvironment.SetTimeAndDate((ushort) currentTime.Hour, (ushort) currentTime.Minute,
+ (ushort) currentTime.Second, (ushort) currentTime.Month, (ushort) currentTime.Day,
+ (ushort) currentTime.Year);
Debug.Console(1, this, "Processor time set to {0}", CrestronEnvironment.GetLocalTime());
}
@@ -780,13 +824,13 @@ namespace PepperDash.Essentials.Core.Fusion
{
// Room info response with custom properties
- string roomConfigResponseArgs = args.Sig.StringValue.Replace("&", "and");
+ var roomConfigResponseArgs = args.Sig.StringValue.Replace("&", "and");
Debug.Console(2, this, "Fusion Response: \n {0}", roomConfigResponseArgs);
try
{
- XmlDocument roomConfigResponse = new XmlDocument();
+ var roomConfigResponse = new XmlDocument();
roomConfigResponse.LoadXml(roomConfigResponseArgs);
@@ -794,13 +838,13 @@ namespace PepperDash.Essentials.Core.Fusion
if (requestRoomConfiguration != null)
{
- RoomInformation roomInformation = new RoomInformation();
+ var roomInformation = new RoomInformation();
foreach (XmlElement e in roomConfigResponse.FirstChild.ChildNodes)
{
if (e.Name == "RoomInformation")
{
- XmlReader roomInfo = new XmlReader(e.OuterXml);
+ var roomInfo = new XmlReader(e.OuterXml);
roomInformation = CrestronXMLSerialization.DeSerializeObject(roomInfo);
}
@@ -808,7 +852,7 @@ namespace PepperDash.Essentials.Core.Fusion
{
foreach (XmlElement el in e)
{
- FusionCustomProperty customProperty = new FusionCustomProperty();
+ var customProperty = new FusionCustomProperty();
if (el.Name == "CustomField")
{
@@ -838,7 +882,9 @@ namespace PepperDash.Essentials.Core.Fusion
var handler = RoomInfoChange;
if (handler != null)
+ {
handler(this, new EventArgs());
+ }
CustomPropertiesBridge.EvaluateRoomInfo(Room.Key, roomInformation);
}
@@ -851,7 +897,6 @@ namespace PepperDash.Essentials.Core.Fusion
//getRoomInfoBusy = false;
//_DynFusion.API.EISC.BooleanInput[Constants.GetRoomInfo].BoolValue = getRoomInfoBusy;
}
-
}
///
@@ -859,130 +904,127 @@ namespace PepperDash.Essentials.Core.Fusion
///
///
///
- protected void FusionRoomSchedule_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
+ protected void FusionRoomSchedule_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender,
+ SigEventArgs args)
{
- Debug.Console(2, this, "Scehdule Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue);
+ Debug.Console(2, this, "Scehdule Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event,
+ args.Sig.Name, args.Sig.StringValue);
- if (args.Sig == FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.ScheduleResponse)
- {
- try
- {
- ScheduleResponse scheduleResponse = new ScheduleResponse();
+ if (args.Sig == FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.ScheduleResponse)
+ {
+ try
+ {
+ var scheduleResponse = new ScheduleResponse();
- XmlDocument message = new XmlDocument();
+ var message = new XmlDocument();
- message.LoadXml(args.Sig.StringValue);
+ message.LoadXml(args.Sig.StringValue);
- var response = message["ScheduleResponse"];
+ var response = message["ScheduleResponse"];
- if (response != null)
- {
- // Check for push notification
- if (response["RequestID"].InnerText == "RVRequest")
- {
- var action = response["Action"];
+ if (response != null)
+ {
+ // Check for push notification
+ if (response["RequestID"].InnerText == "RVRequest")
+ {
+ var action = response["Action"];
- if (action.OuterXml.IndexOf("RequestSchedule") > -1)
- {
- PushNotificationTimer.Reset(PushNotificationTimeout, PushNotificationTimeout);
- }
- }
- else // Not a push notification
- {
- CurrentSchedule = new RoomSchedule(); // Clear Current Schedule
- CurrentMeeting = null; // Clear Current Meeting
- NextMeeting = null; // Clear Next Meeting
+ if (action.OuterXml.IndexOf("RequestSchedule", StringComparison.Ordinal) > -1)
+ {
+ _pushNotificationTimer.Reset(PushNotificationTimeout, PushNotificationTimeout);
+ }
+ }
+ else // Not a push notification
+ {
+ _currentSchedule = new RoomSchedule(); // Clear Current Schedule
+ _currentMeeting = null; // Clear Current Meeting
+ _nextMeeting = null; // Clear Next Meeting
- bool isNextMeeting = false;
+ var isNextMeeting = false;
- foreach (XmlElement element in message.FirstChild.ChildNodes)
- {
- if (element.Name == "RequestID")
- {
- scheduleResponse.RequestID = element.InnerText;
- }
- else if (element.Name == "RoomID")
- {
- scheduleResponse.RoomID = element.InnerText;
- }
- else if (element.Name == "RoomName")
- {
- scheduleResponse.RoomName = element.InnerText;
- }
- else if (element.Name == "Event")
- {
- Debug.Console(2, this, "Event Found:\n{0}", element.OuterXml);
+ foreach (XmlElement element in message.FirstChild.ChildNodes)
+ {
+ if (element.Name == "RequestID")
+ {
+ scheduleResponse.RequestID = element.InnerText;
+ }
+ else if (element.Name == "RoomID")
+ {
+ scheduleResponse.RoomID = element.InnerText;
+ }
+ else if (element.Name == "RoomName")
+ {
+ scheduleResponse.RoomName = element.InnerText;
+ }
+ else if (element.Name == "Event")
+ {
+ Debug.Console(2, this, "Event Found:\n{0}", element.OuterXml);
- XmlReader reader = new XmlReader(element.OuterXml);
+ var reader = new XmlReader(element.OuterXml);
- Event tempEvent = new Event();
+ var tempEvent = CrestronXMLSerialization.DeSerializeObject(reader);
- tempEvent = CrestronXMLSerialization.DeSerializeObject(reader);
+ scheduleResponse.Events.Add(tempEvent);
- scheduleResponse.Events.Add(tempEvent);
+ // Check is this is the current event
+ if (tempEvent.dtStart <= DateTime.Now && tempEvent.dtEnd >= DateTime.Now)
+ {
+ _currentMeeting = tempEvent; // Set Current Meeting
+ isNextMeeting = true; // Flag that next element is next meeting
+ }
- // Check is this is the current event
- if (tempEvent.dtStart <= DateTime.Now && tempEvent.dtEnd >= DateTime.Now)
- {
- CurrentMeeting = tempEvent; // Set Current Meeting
- isNextMeeting = true; // Flag that next element is next meeting
- }
+ if (isNextMeeting)
+ {
+ _nextMeeting = tempEvent; // Set Next Meeting
+ isNextMeeting = false;
+ }
- if (isNextMeeting)
- {
- NextMeeting = tempEvent; // Set Next Meeting
- isNextMeeting = false;
- }
+ _currentSchedule.Meetings.Add(tempEvent);
+ }
+ }
- CurrentSchedule.Meetings.Add(tempEvent);
- }
+ PrintTodaysSchedule();
- }
+ if (!_isRegisteredForSchedulePushNotifications)
+ {
+ _pollTimer.Reset(SchedulePollInterval, SchedulePollInterval);
+ }
- PrintTodaysSchedule();
-
- if (!IsRegisteredForSchedulePushNotifications)
- PollTimer.Reset(SchedulePollInterval, SchedulePollInterval);
-
- // Fire Schedule Change Event
- var handler = ScheduleChange;
-
- if (handler != null)
- {
- handler(this, new ScheduleChangeEventArgs() { Schedule = CurrentSchedule });
- }
-
- }
- }
-
-
-
- }
- catch (Exception e)
- {
- Debug.Console(1, this, "Error parsing ScheduleResponse: {0}", e);
- }
- }
- else if (args.Sig == FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.CreateResponse)
- {
- Debug.Console(2, this, "Create Meeting Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue);
- }
+ // Fire Schedule Change Event
+ var handler = ScheduleChange;
+ if (handler != null)
+ {
+ handler(this, new ScheduleChangeEventArgs {Schedule = _currentSchedule});
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.Console(1, this, "Error parsing ScheduleResponse: {0}", e);
+ }
+ }
+ else if (args.Sig == FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.CreateResponse)
+ {
+ Debug.Console(2, this, "Create Meeting Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event,
+ args.Sig.Name, args.Sig.StringValue);
+ }
}
///
/// Prints today's schedule to console for debugging
///
- void PrintTodaysSchedule()
+ private void PrintTodaysSchedule()
{
if (Debug.Level > 1)
{
- if (CurrentSchedule.Meetings.Count > 0)
+ if (_currentSchedule.Meetings.Count > 0)
{
Debug.Console(1, this, "Today's Schedule for '{0}'\n", Room.Name);
- foreach (Event e in CurrentSchedule.Meetings)
+ foreach (var e in _currentSchedule.Meetings)
{
Debug.Console(1, this, "Subject: {0}", e.Subject);
Debug.Console(1, this, "Organizer: {0}", e.Organizer);
@@ -995,63 +1037,62 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
- protected virtual void SetUpSources()
- {
- // Sources
- var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsRoomBase).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 Devices.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)
+ protected virtual void SetUpSources()
+ {
+ // Sources
+ var dict = ConfigReader.ConfigObject.GetSourceListForKey(Room.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)
{
- var usageDevice = kvp.Value.SourceDevice as IUsageTracking;
-
- if (usageDevice != null)
+ TryAddRouteActionSigs(JoinMap.Display1SetTopBoxSourceStart.AttributeName + " " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
+ i++;
+ if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
{
- usageDevice.UsageTracker = new UsageTracking(usageDevice as Device);
- usageDevice.UsageTracker.UsageIsTracked = true;
- usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded);
+ break;
}
}
-
- }
- else
- {
- Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
- (Room as EssentialsRoomBase).SourceListKey, Room.Key);
- }
- }
+
+ var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
+ i = 1;
+ foreach (var kvp in discPlayers)
+ {
+ TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
+ i++;
+ if (i > JoinMap.Display1DiscPlayerSourceStart.JoinSpan) // We only have five spots
+ {
+ break;
+ }
+ }
+
+ var laptops = dict.Where(d => d.Value.SourceDevice is Devices.Laptop);
+ i = 1;
+ foreach (var kvp in laptops)
+ {
+ TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
+ i++;
+ if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
+ {
+ break;
+ }
+ }
+
+ foreach (var usageDevice in dict.Select(kvp => kvp.Value.SourceDevice).OfType())
+ {
+ usageDevice.UsageTracker = new UsageTracking(usageDevice as Device) {UsageIsTracked = true};
+ usageDevice.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
+ }
+ }
+ else
+ {
+ Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
+ Room.SourceListKey, Room.Key);
+ }
+ }
///
/// Collects usage data from source and sends to Fusion
@@ -1059,24 +1100,31 @@ namespace PepperDash.Essentials.Core.Fusion
///
///
protected void UsageTracker_DeviceUsageEnded(object sender, DeviceUsageEventArgs e)
- {
+ {
var deviceTracker = sender as UsageTracking;
- var configDevice = ConfigReader.ConfigObject.Devices.Where(d => d.Key.Equals(deviceTracker.Parent));
+ if (deviceTracker == null)
+ {
+ return;
+ }
- string group = ConfigReader.GetGroupForDeviceKey(deviceTracker.Parent.Key);
+ var group = ConfigReader.GetGroupForDeviceKey(deviceTracker.Parent.Key);
- string currentMeetingId = "-";
+ var currentMeetingId = "-";
- if (CurrentMeeting != null)
- currentMeetingId = CurrentMeeting.MeetingID;
+ if (_currentMeeting != null)
+ {
+ currentMeetingId = _currentMeeting.MeetingID;
+ }
//String Format: "USAGE||[Date YYYY-MM-DD]||[Time HH-mm-ss]||TIME||[Asset_Type]||[Asset_Name]||[Minutes_used]||[Asset_ID]||[Meeting_ID]"
// [Asset_ID] property does not appear to be used in Crestron SSI examples. They are sending "-" instead so that's what is replicated here
- string deviceUsage = string.Format("USAGE||{0}||{1}||TIME||{2}||{3}||-||{4}||-||{5}||{6}||\r\n", e.UsageEndTime.ToString("yyyy-MM-dd"), e.UsageEndTime.ToString("HH:mm:ss"),
- group, deviceTracker.Parent.Name, e.MinutesUsed, "-", currentMeetingId);
+ var deviceUsage = string.Format("USAGE||{0}||{1}||TIME||{2}||{3}||-||{4}||-||{5}||{6}||\r\n",
+ e.UsageEndTime.ToString("yyyy-MM-dd"), e.UsageEndTime.ToString("HH:mm:ss"),
+ @group, deviceTracker.Parent.Name, e.MinutesUsed, "-", currentMeetingId);
- Debug.Console(1, this, "Device usage for: {0} ended at {1}. In use for {2} minutes", deviceTracker.Parent.Name, e.UsageEndTime, e.MinutesUsed);
+ Debug.Console(1, this, "Device usage for: {0} ended at {1}. In use for {2} minutes",
+ deviceTracker.Parent.Name, e.UsageEndTime, e.MinutesUsed);
FusionRoom.DeviceUsage.InputSig.StringValue = deviceUsage;
@@ -1084,41 +1132,51 @@ namespace PepperDash.Essentials.Core.Fusion
}
- protected void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc)
- {
- Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}",
- attrName, attrNum, pSrc.Key);
- try
- {
- var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig);
- // Need feedback when this source is selected
- // Event handler, added below, will compare source changes with this sig dict
- SourceToFeedbackSigs.Add(pSrc, sigD.InputSig);
+ protected void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc)
+ {
+ Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}",
+ attrName, attrNum, pSrc.Key);
+ try
+ {
+ var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig);
+ // Need feedback when this source is selected
+ // Event handler, added below, will compare source changes with this sig dict
+ _sourceToFeedbackSigs.Add(pSrc, sigD.InputSig);
- // And respond to selection in Fusion
- sigD.OutputSig.SetSigFalseAction(() => (Room as IRunRouteAction).RunRouteAction(routeKey, Room.SourceListKey));
- }
- catch (Exception)
- {
- Debug.Console(2, this, "Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING", attrNum, attrName, pSrc.Key);
- }
- }
+ // And respond to selection in Fusion
+ sigD.OutputSig.SetSigFalseAction(() =>
+ {
+ var runRouteAction = Room as IRunRouteAction;
+ if (runRouteAction != null)
+ {
+ runRouteAction.RunRouteAction(routeKey, Room.SourceListKey);
+ }
+ });
+ }
+ catch (Exception)
+ {
+ Debug.Console(2, this, "Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING",
+ attrNum, attrName, pSrc.Key);
+ }
+ }
- ///
- ///
- ///
- void SetUpCommunitcationMonitors()
- {
+ ///
+ ///
+ ///
+ private void SetUpCommunitcationMonitors()
+ {
uint displayNum = 0;
uint touchpanelNum = 0;
uint xpanelNum = 0;
- // Attach to all room's devices with monitors.
- //foreach (var dev in DeviceManager.Devices)
- foreach (var dev in DeviceManager.GetDevices())
- {
- if (!(dev is ICommunicationMonitor))
- continue;
+ // Attach to all room's devices with monitors.
+ //foreach (var dev in DeviceManager.Devices)
+ foreach (var dev in DeviceManager.GetDevices())
+ {
+ if (!(dev is ICommunicationMonitor))
+ {
+ continue;
+ }
string attrName = null;
uint attrNum = 1;
@@ -1140,10 +1198,12 @@ namespace PepperDash.Essentials.Core.Fusion
{
attrNum = attrNum + touchpanelNum;
- if (attrNum > 10)
+ if (attrNum > JoinMap.XpanelOnlineStart.JoinSpan)
+ {
continue;
- attrName = "Online - XPanel " + attrNum;
- attrNum += 160;
+ }
+ attrName = JoinMap.XpanelOnlineStart.AttributeName + " " + attrNum;
+ attrNum += JoinMap.XpanelOnlineStart.JoinNumber;
touchpanelNum++;
}
@@ -1151,54 +1211,58 @@ namespace PepperDash.Essentials.Core.Fusion
{
attrNum = attrNum + xpanelNum;
- if (attrNum > 10)
+ if (attrNum > JoinMap.TouchpanelOnlineStart.JoinSpan)
+ {
continue;
- attrName = "Online - Touch Panel " + attrNum;
- attrNum += 150;
+ }
+ attrName = JoinMap.TouchpanelOnlineStart.AttributeName + " " + attrNum;
+ attrNum += JoinMap.TouchpanelOnlineStart.JoinNumber;
xpanelNum++;
}
}
- //else
- if (dev is DisplayBase)
- {
- attrNum = attrNum + displayNum;
- if (attrNum > 10)
- continue;
- attrName = "Online - Display " + attrNum;
- attrNum += 170;
+ //else
+ if (dev is DisplayBase)
+ {
+ attrNum = attrNum + displayNum;
+ if (attrNum > JoinMap.DisplayOnlineStart.JoinSpan)
+ {
+ continue;
+ }
+ attrName = JoinMap.DisplayOnlineStart.AttributeName + " " + attrNum;
+ attrNum += JoinMap.DisplayOnlineStart.JoinNumber;
displayNum++;
- }
- //else if (dev is DvdDeviceBase)
- //{
- // if (attrNum > 5)
- // continue;
- // attrName = "Device Ok - DVD " + attrNum;
- // attrNum += 260;
- //}
- // add set top box
+ }
+ //else if (dev is DvdDeviceBase)
+ //{
+ // if (attrNum > 5)
+ // continue;
+ // attrName = "Device Ok - DVD " + attrNum;
+ // attrNum += 260;
+ //}
+ // add set top box
- // add Cresnet roll-up
+ // add Cresnet roll-up
- // add DM-devices roll-up
+ // add DM-devices roll-up
- if (attrName != null)
- {
- // Link comm status to sig and update
- var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly);
- var smd = dev as ICommunicationMonitor;
- sigD.InputSig.BoolValue = smd.CommunicationMonitor.Status == MonitorStatus.IsOk;
- smd.CommunicationMonitor.StatusChange += (o, a) =>
- { sigD.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; };
- Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", dev.Key, attrName);
- }
- }
- }
+ if (attrName != null)
+ {
+ // Link comm status to sig and update
+ var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly);
+ var smd = dev as ICommunicationMonitor;
+ sigD.InputSig.BoolValue = smd.CommunicationMonitor.Status == MonitorStatus.IsOk;
+ smd.CommunicationMonitor.StatusChange +=
+ (o, a) => { sigD.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; };
+ Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", dev.Key, attrName);
+ }
+ }
+ }
- protected virtual void SetUpDisplay()
- {
+ protected virtual void SetUpDisplay()
+ {
try
{
//Setup Display Usage Monitoring
@@ -1207,35 +1271,52 @@ namespace PepperDash.Essentials.Core.Fusion
// Consider updating this in multiple display systems
- foreach (DisplayBase display in displays)
+ foreach (var display in displays.Cast())
{
- display.UsageTracker = new UsageTracking(display);
- display.UsageTracker.UsageIsTracked = true;
- display.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded);
+ display.UsageTracker = new UsageTracking(display) {UsageIsTracked = true};
+ display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
}
- var defaultDisplay = (Room as IHasDefaultDisplay).DefaultDisplay as DisplayBase;
+ var hasDefaultDisplay = Room as IHasDefaultDisplay;
+ if (hasDefaultDisplay == null)
+ {
+ return;
+ }
+ var defaultDisplay = hasDefaultDisplay.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(b => { if (!b) defaultDisplay.PowerOn(); });
- var dispPowerOffAction = new Action(b => { if (!b) defaultDisplay.PowerOff(); });
+ var dispPowerOnAction = new Action(b =>
+ {
+ if (!b)
+ {
+ defaultDisplay.PowerOn();
+ }
+ });
+ var dispPowerOffAction = new Action(b =>
+ {
+ if (!b)
+ {
+ defaultDisplay.PowerOff();
+ }
+ });
// Display to fusion room sigs
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
- FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
+ FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
- MapDisplayToRoomJoins(1, 158, defaultDisplay);
+ MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay);
- var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
+ var deviceConfig =
+ ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
//Check for existing asset in GUIDs collection
- var tempAsset = new FusionAsset();
+ FusionAsset tempAsset;
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
@@ -1244,11 +1325,13 @@ namespace PepperDash.Essentials.Core.Fusion
else
{
// Create a new asset
- tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", "");
+ 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);
+ var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
+ tempAsset.InstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
@@ -1257,13 +1340,14 @@ namespace PepperDash.Essentials.Core.Fusion
{
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
if (defaultDisplay is IDisplayUsage)
+ {
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
+ }
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
-
}
- // Use extension methods
+ // Use extension methods
dispAsset.TrySetMakeModel(defaultDisplay);
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
}
@@ -1271,323 +1355,397 @@ namespace PepperDash.Essentials.Core.Fusion
{
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
}
-
- }
+ }
///
/// Maps room attributes to a display at a specified index
///
- ///
- /// a
- protected virtual void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
+ ///
+ ///
+ ///
+ /// a
+ protected virtual void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display)
{
- string displayName = string.Format("Display {0} - ", displayIndex);
+ var displayName = string.Format("Display {0} - ", displayIndex);
- if (display == (Room as IHasDefaultDisplay).DefaultDisplay)
+ var hasDefaultDisplay = Room as IHasDefaultDisplay;
+ if (hasDefaultDisplay == null || display != hasDefaultDisplay.DefaultDisplay)
{
- // Display volume
- var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
- defaultDisplayVolume.OutputSig.UserObject = new Action(b => (display as IBasicVolumeWithFeedback).SetVolume(b));
- (display as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(defaultDisplayVolume.InputSig);
-
- // Power on
- var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
- defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => { if (!b) display.PowerOn(); });
-
- // Power Off
- var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
- defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => { if (!b) display.PowerOff(); }); ;
-
-
- var defaultTwoWayDisplay = display as IHasPowerControlWithFeedback;
- if (defaultTwoWayDisplay != null)
+ return;
+ }
+ // Display volume
+ var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.AttributeName,
+ eSigIoMask.InputOutputSig);
+ defaultDisplayVolume.OutputSig.UserObject = new Action(b =>
+ {
+ var basicVolumeWithFeedback = display as IBasicVolumeWithFeedback;
+ if (basicVolumeWithFeedback == null)
{
- defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
- defaultTwoWayDisplay.PowerIsOnFeedback.LinkComplementInputSig(defaultDisplayPowerOff.InputSig);
+ return;
}
- // Current Source
- var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
- defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => { if (!b) (Room as IRunRouteAction).RunRouteAction("roomOff", Room.SourceListKey); }); ;
+ basicVolumeWithFeedback.SetVolume(b);
+ basicVolumeWithFeedback.VolumeLevelFeedback.LinkInputSig(defaultDisplayVolume.InputSig);
+ });
+
+
+ // Power on
+ var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint) joinOffset, displayName + "Power On",
+ eSigIoMask.InputOutputSig);
+ defaultDisplayPowerOn.OutputSig.UserObject = new Action(b =>
+ {
+ if (!b)
+ {
+ display.PowerOn();
+ }
+ });
+
+ // Power Off
+ var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 1, displayName + "Power Off",
+ eSigIoMask.InputOutputSig);
+ defaultDisplayPowerOn.OutputSig.UserObject = new Action(b =>
+ {
+ if (!b)
+ {
+ display.PowerOff();
+ }
+ });
+
+
+ var defaultTwoWayDisplay = display as IHasPowerControlWithFeedback;
+ if (defaultTwoWayDisplay != null)
+ {
+ defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
+ defaultTwoWayDisplay.PowerIsOnFeedback.LinkComplementInputSig(defaultDisplayPowerOff.InputSig);
}
+
+ // Current Source
+ var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 8,
+ displayName + "Source None", eSigIoMask.InputOutputSig);
+ defaultDisplaySourceNone.OutputSig.UserObject = new Action(b =>
+ {
+ if (!b)
+ {
+ var runRouteAction = Room as IRunRouteAction;
+ if (runRouteAction != null)
+ {
+ runRouteAction.RunRouteAction("roomOff", Room.SourceListKey);
+ }
+ }
+ });
}
- void SetUpError()
- {
- // Roll up ALL device errors
- ErrorMessageRollUp = new StatusMonitorCollection(this);
- foreach (var dev in DeviceManager.GetDevices())
- {
- var md = dev as ICommunicationMonitor;
- if (md != null)
- {
- ErrorMessageRollUp.AddMonitor(md.CommunicationMonitor);
- Debug.Console(2, this, "Adding '{0}' to room's overall error monitor", md.CommunicationMonitor.Parent.Key);
- }
- }
- ErrorMessageRollUp.Start();
- FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message;
- ErrorMessageRollUp.StatusChange += (o, a) =>
- {
- FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message;
- };
-
- }
+ private void SetUpError()
+ {
+ // Roll up ALL device errors
+ _errorMessageRollUp = new StatusMonitorCollection(this);
+ foreach (var dev in DeviceManager.GetDevices())
+ {
+ var md = dev as ICommunicationMonitor;
+ if (md != null)
+ {
+ _errorMessageRollUp.AddMonitor(md.CommunicationMonitor);
+ Debug.Console(2, this, "Adding '{0}' to room's overall error monitor",
+ md.CommunicationMonitor.Parent.Key);
+ }
+ }
+ _errorMessageRollUp.Start();
+ FusionRoom.ErrorMessage.InputSig.StringValue = _errorMessageRollUp.Message;
+ _errorMessageRollUp.StatusChange +=
+ (o, a) => { FusionRoom.ErrorMessage.InputSig.StringValue = _errorMessageRollUp.Message; };
+ }
///
/// Sets up a local occupancy sensor, such as one attached to a Fusion Scheduling panel. The occupancy status of the room will be read from Fusion
///
- void SetUpLocalOccupancy()
+ private void SetUpLocalOccupancy()
{
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
- FusionRoom.FusionAssetStateChange += new FusionAssetStateEventHandler(FusionRoom_FusionAssetStateChange);
+ FusionRoom.FusionAssetStateChange += FusionRoom_FusionAssetStateChange;
// Build Occupancy Asset?
// Link sigs?
//Room.SetRoomOccupancy(this as IOccupancyStatusProvider, 0);
-
-
}
- void FusionRoom_FusionAssetStateChange(FusionBase device, FusionAssetStateEventArgs args)
+ private void FusionRoom_FusionAssetStateChange(FusionBase device, FusionAssetStateEventArgs args)
{
- if (args.EventId == FusionAssetEventId.RoomOccupiedReceivedEventId || args.EventId == FusionAssetEventId.RoomUnoccupiedReceivedEventId)
+ if (args.EventId == FusionAssetEventId.RoomOccupiedReceivedEventId ||
+ args.EventId == FusionAssetEventId.RoomUnoccupiedReceivedEventId)
+ {
RoomIsOccupiedFeedback.FireUpdate();
-
+ }
}
///
/// Sets up remote occupancy that will relay the occupancy status determined by local system devices to Fusion
///
- void SetUpRemoteOccupancy()
- {
-
+ private void SetUpRemoteOccupancy()
+ {
// Need to have the room occupancy object first and somehow determine the slot number of the Occupancy asset but will not be able to use the UID from config likely.
// Consider defining an object just for Room Occupancy (either eAssetType.Occupancy Sensor (local) or eAssetType.RemoteOccupancySensor (from Fusion sched. panel)) and reserving slot 4 for that asset (statics would start at 5)
//if (Room.OccupancyObj != null)
//{
- var tempOccAsset = GUIDs.OccupancyAsset;
-
- if(tempOccAsset == null)
- {
- FusionOccSensor = new FusionOccupancySensorAsset(eAssetType.OccupancySensor);
- tempOccAsset = FusionOccSensor;
- }
+ var tempOccAsset = _guiDs.OccupancyAsset;
- var occSensorAsset = FusionRoom.CreateOccupancySensorAsset(tempOccAsset.SlotNumber, tempOccAsset.Name, "Occupancy Sensor", tempOccAsset.InstanceId);
+ if (tempOccAsset == null)
+ {
+ FusionOccSensor = new FusionOccupancySensorAsset(eAssetType.OccupancySensor);
+ tempOccAsset = FusionOccSensor;
+ }
- occSensorAsset.RoomOccupied.AddSigToRVIFile = true;
+ var occSensorAsset = FusionRoom.CreateOccupancySensorAsset(tempOccAsset.SlotNumber, tempOccAsset.Name,
+ "Occupancy Sensor", tempOccAsset.InstanceId);
- var occSensorShutdownMinutes = FusionRoom.CreateOffsetUshortSig(70, "Occ Shutdown - Minutes", eSigIoMask.InputOutputSig);
-
- // Tie to method on occupancy object
- //occSensorShutdownMinutes.OutputSig.UserObject(new Action(ushort)(b => Room.OccupancyObj.SetShutdownMinutes(b));
+ occSensorAsset.RoomOccupied.AddSigToRVIFile = true;
+
+ //var occSensorShutdownMinutes = FusionRoom.CreateOffsetUshortSig(70, "Occ Shutdown - Minutes", eSigIoMask.InputOutputSig);
+
+ // Tie to method on occupancy object
+ //occSensorShutdownMinutes.OutputSig.UserObject(new Action(ushort)(b => Room.OccupancyObj.SetShutdownMinutes(b));
- RoomOccupancyRemoteStringFeedback = new StringFeedback(() => _roomOccupancyRemoteString);
- Room.RoomOccupancy.RoomIsOccupiedFeedback.LinkInputSig(occSensorAsset.RoomOccupied.InputSig);
- Room.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
- RoomOccupancyRemoteStringFeedback.LinkInputSig(occSensorAsset.RoomOccupancyInfo.InputSig);
-
+ RoomOccupancyRemoteStringFeedback = new StringFeedback(() => _roomOccupancyRemoteString);
+ Room.RoomOccupancy.RoomIsOccupiedFeedback.LinkInputSig(occSensorAsset.RoomOccupied.InputSig);
+ Room.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
+ RoomOccupancyRemoteStringFeedback.LinkInputSig(occSensorAsset.RoomOccupancyInfo.InputSig);
+
//}
}
- void RoomIsOccupiedFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ private void RoomIsOccupiedFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
_roomOccupancyRemoteString = String.Format(RemoteOccupancyXml, e.BoolValue ? "Occupied" : "Unoccupied");
RoomOccupancyRemoteStringFeedback.FireUpdate();
}
- ///
- /// Helper to get the number from the end of a device's key string
- ///
- /// -1 if no number matched
- int ExtractNumberFromKey(string key)
- {
+ ///
+ /// Helper to get the number from the end of a device's key string
+ ///
+ /// -1 if no number matched
+ private int ExtractNumberFromKey(string key)
+ {
var capture = System.Text.RegularExpressions.Regex.Match(key, @"\b(\d+)");
- if (!capture.Success)
- return -1;
- else return Convert.ToInt32(capture.Groups[1].Value);
- }
+ if (!capture.Success)
+ {
+ return -1;
+ }
+ return Convert.ToInt32(capture.Groups[1].Value);
+ }
- ///
- /// Event handler for when room source changes
- ///
- protected void Room_CurrentSourceInfoChange(SourceListItem info, ChangeType type)
- {
- // Handle null. Nothing to do when switching from or to null
- if (info == null || info.SourceDevice == null)
- return;
+ ///
+ /// Event handler for when room source changes
+ ///
+ protected void Room_CurrentSourceInfoChange(SourceListItem info, ChangeType type)
+ {
+ // Handle null. Nothing to do when switching from or to null
+ if (info == null || info.SourceDevice == null)
+ {
+ return;
+ }
- var dev = info.SourceDevice;
- if (type == ChangeType.WillChange)
- {
- if (SourceToFeedbackSigs.ContainsKey(dev))
- SourceToFeedbackSigs[dev].BoolValue = false;
- }
- else
- {
- if (SourceToFeedbackSigs.ContainsKey(dev))
- SourceToFeedbackSigs[dev].BoolValue = true;
+ var dev = info.SourceDevice;
+ if (type == ChangeType.WillChange)
+ {
+ if (_sourceToFeedbackSigs.ContainsKey(dev))
+ {
+ _sourceToFeedbackSigs[dev].BoolValue = false;
+ }
+ }
+ else
+ {
+ if (_sourceToFeedbackSigs.ContainsKey(dev))
+ {
+ _sourceToFeedbackSigs[dev].BoolValue = true;
+ }
//var name = (room == null ? "" : room.Name);
- CurrentRoomSourceNameSig.InputSig.StringValue = info.SourceDevice.Name;
- }
- }
+ CurrentRoomSourceNameSig.InputSig.StringValue = info.SourceDevice.Name;
+ }
+ }
- protected void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args)
- {
+ protected void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args)
+ {
+ // The sig/UO method: Need separate handlers for fixed and user sigs, all flavors,
+ // even though they all contain sigs.
- // The sig/UO method: Need separate handlers for fixed and user sigs, all flavors,
- // even though they all contain sigs.
+ var sigData = args.UserConfiguredSigDetail as BooleanSigDataFixedName;
- var sigData = (args.UserConfiguredSigDetail as BooleanSigDataFixedName);
- if (sigData != null)
- {
- var outSig = sigData.OutputSig;
- if (outSig.UserObject is Action)
- (outSig.UserObject as Action).Invoke(outSig.BoolValue);
- else if (outSig.UserObject is Action)
- (outSig.UserObject as Action).Invoke(outSig.UShortValue);
- else if (outSig.UserObject is Action)
- (outSig.UserObject as Action).Invoke(outSig.StringValue);
- return;
- }
+ BoolOutputSig outSig;
+ if (sigData != null)
+ {
+ outSig = sigData.OutputSig;
+ if (outSig.UserObject is Action)
+ {
+ (outSig.UserObject as Action).Invoke(outSig.BoolValue);
+ }
+ else if (outSig.UserObject is Action)
+ {
+ (outSig.UserObject as Action).Invoke(outSig.UShortValue);
+ }
+ else if (outSig.UserObject is Action)
+ {
+ (outSig.UserObject as Action).Invoke(outSig.StringValue);
+ }
+ return;
+ }
- var attrData = (args.UserConfiguredSigDetail as BooleanSigData);
- if (attrData != null)
- {
- var outSig = attrData.OutputSig;
- if (outSig.UserObject is Action)
- (outSig.UserObject as Action).Invoke(outSig.BoolValue);
- else if (outSig.UserObject is Action)
- (outSig.UserObject as Action).Invoke(outSig.UShortValue);
- else if (outSig.UserObject is Action)
- (outSig.UserObject as Action).Invoke(outSig.StringValue);
- return;
- }
-
- }
- }
+ var attrData = (args.UserConfiguredSigDetail as BooleanSigData);
+ if (attrData == null)
+ {
+ return;
+ }
+ outSig = attrData.OutputSig;
+ if (outSig.UserObject is Action)
+ {
+ (outSig.UserObject as Action).Invoke(outSig.BoolValue);
+ }
+ else if (outSig.UserObject is Action)
+ {
+ (outSig.UserObject as Action).Invoke(outSig.UShortValue);
+ }
+ else if (outSig.UserObject is Action)
+ {
+ (outSig.UserObject as Action).Invoke(outSig.StringValue);
+ }
+ }
+ }
- public static class FusionRoomExtensions
- {
- ///
- /// Creates and returns a fusion attribute. The join number will match the established Simpl
- /// standard of 50+, and will generate a 50+ join in the RVI. It calls
- /// FusionRoom.AddSig with join number - 49
- ///
- /// The new attribute
- public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
- {
- if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
- number -= 49;
- fr.AddSig(eSigType.Bool, number, name, mask);
- return fr.UserDefinedBooleanSigDetails[number];
- }
+ public static class FusionRoomExtensions
+ {
+ ///
+ /// Creates and returns a fusion attribute. The join number will match the established Simpl
+ /// standard of 50+, and will generate a 50+ join in the RVI. It calls
+ /// FusionRoom.AddSig with join number - 49
+ ///
+ /// The new attribute
+ public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
+ {
+ if (number < 50)
+ {
+ throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
+ }
+ number -= 49;
+ fr.AddSig(eSigType.Bool, number, name, mask);
+ return fr.UserDefinedBooleanSigDetails[number];
+ }
- ///
- /// Creates and returns a fusion attribute. The join number will match the established Simpl
- /// standard of 50+, and will generate a 50+ join in the RVI. It calls
- /// FusionRoom.AddSig with join number - 49
- ///
- /// The new attribute
- public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
- {
- if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
- number -= 49;
- fr.AddSig(eSigType.UShort, number, name, mask);
- return fr.UserDefinedUShortSigDetails[number];
- }
+ ///
+ /// Creates and returns a fusion attribute. The join number will match the established Simpl
+ /// standard of 50+, and will generate a 50+ join in the RVI. It calls
+ /// FusionRoom.AddSig with join number - 49
+ ///
+ /// The new attribute
+ public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
+ {
+ if (number < 50)
+ {
+ throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
+ }
+ number -= 49;
+ fr.AddSig(eSigType.UShort, number, name, mask);
+ return fr.UserDefinedUShortSigDetails[number];
+ }
- ///
- /// Creates and returns a fusion attribute. The join number will match the established Simpl
- /// standard of 50+, and will generate a 50+ join in the RVI. It calls
- /// FusionRoom.AddSig with join number - 49
- ///
- /// The new attribute
- public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
- {
- if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
- number -= 49;
- fr.AddSig(eSigType.String, number, name, mask);
- return fr.UserDefinedStringSigDetails[number];
- }
+ ///
+ /// Creates and returns a fusion attribute. The join number will match the established Simpl
+ /// standard of 50+, and will generate a 50+ join in the RVI. It calls
+ /// FusionRoom.AddSig with join number - 49
+ ///
+ /// The new attribute
+ public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
+ {
+ if (number < 50)
+ {
+ throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
+ }
+ number -= 49;
+ fr.AddSig(eSigType.String, number, name, mask);
+ return fr.UserDefinedStringSigDetails[number];
+ }
- ///
- /// Creates and returns a static asset
- ///
- /// the new asset
- public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type, string instanceId)
- {
+ ///
+ /// Creates and returns a static asset
+ ///
+ /// the new asset
+ public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type,
+ string instanceId)
+ {
Debug.Console(0, "Adding Fusion Static Asset '{0}' to slot {1} with GUID: '{2}'", name, number, instanceId);
- fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId);
- return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset;
- }
+ fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId);
+ return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset;
+ }
- public static FusionOccupancySensor CreateOccupancySensorAsset(this FusionRoom fr, uint number, string name, string type, string instanceId)
+ public static FusionOccupancySensor CreateOccupancySensorAsset(this FusionRoom fr, uint number, string name,
+ string type, string instanceId)
{
- Debug.Console(0, "Adding Fusion Occupancy Sensor Asset '{0}' to slot {1} with GUID: '{2}'", name, number, instanceId);
+ Debug.Console(0, "Adding Fusion Occupancy Sensor Asset '{0}' to slot {1} with GUID: '{2}'", name, number,
+ instanceId);
fr.AddAsset(eAssetType.OccupancySensor, number, name, type, instanceId);
return fr.UserConfigurableAssetDetails[number].Asset as FusionOccupancySensor;
}
- }
+ }
- //************************************************************************************************
- ///
- /// Extensions to enhance Fusion room, asset and signal creation.
- ///
- public static class FusionStaticAssetExtensions
- {
- ///
- /// Tries to set a Fusion asset with the make and model of a device.
- /// If the provided Device is IMakeModel, will set the corresponding parameters on the fusion static asset.
- /// Otherwise, does nothing.
- ///
- public static void TrySetMakeModel(this FusionStaticAsset asset, Device device)
- {
- var mm = device as IMakeModel;
- if (mm != null)
- {
- asset.ParamMake.Value = mm.DeviceMake;
- asset.ParamModel.Value = mm.DeviceModel;
- }
- }
+ //************************************************************************************************
+ ///
+ /// Extensions to enhance Fusion room, asset and signal creation.
+ ///
+ public static class FusionStaticAssetExtensions
+ {
+ ///
+ /// Tries to set a Fusion asset with the make and model of a device.
+ /// If the provided Device is IMakeModel, will set the corresponding parameters on the fusion static asset.
+ /// Otherwise, does nothing.
+ ///
+ public static void TrySetMakeModel(this FusionStaticAsset asset, Device device)
+ {
+ var mm = device as IMakeModel;
+ if (mm != null)
+ {
+ asset.ParamMake.Value = mm.DeviceMake;
+ asset.ParamModel.Value = mm.DeviceModel;
+ }
+ }
- ///
- /// Tries to attach the AssetError input on a Fusion asset to a Device's
- /// CommunicationMonitor.StatusChange event. Does nothing if the device is not
- /// IStatusMonitor
- ///
- ///
- ///
- public static void TryLinkAssetErrorToCommunication(this FusionStaticAsset asset, Device device)
- {
- if (device is ICommunicationMonitor)
- {
- var monitor = (device as ICommunicationMonitor).CommunicationMonitor;
- monitor.StatusChange += (o, a) =>
- {
- // Link connected and error inputs on asset
- asset.Connected.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
- asset.AssetError.InputSig.StringValue = a.Status.ToString();
- };
- // set current value
- asset.Connected.InputSig.BoolValue = monitor.Status == MonitorStatus.IsOk;
- asset.AssetError.InputSig.StringValue = monitor.Status.ToString();
- }
- }
- }
+ ///
+ /// Tries to attach the AssetError input on a Fusion asset to a Device's
+ /// CommunicationMonitor.StatusChange event. Does nothing if the device is not
+ /// IStatusMonitor
+ ///
+ ///
+ ///
+ public static void TryLinkAssetErrorToCommunication(this FusionStaticAsset asset, Device device)
+ {
+ if (device is ICommunicationMonitor)
+ {
+ var monitor = (device as ICommunicationMonitor).CommunicationMonitor;
+ monitor.StatusChange += (o, a) =>
+ {
+ // Link connected and error inputs on asset
+ asset.Connected.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
+ asset.AssetError.InputSig.StringValue = a.Status.ToString();
+ };
+ // set current value
+ asset.Connected.InputSig.BoolValue = monitor.Status == MonitorStatus.IsOk;
+ asset.AssetError.InputSig.StringValue = monitor.Status.ToString();
+ }
+ }
+ }
public class RoomInformation
{
+ public RoomInformation()
+ {
+ FusionCustomProperties = new List();
+ }
+
public string ID { get; set; }
public string Name { get; set; }
public string Location { get; set; }
@@ -1598,27 +1756,22 @@ namespace PepperDash.Essentials.Core.Fusion
public string SubErrorMsg { get; set; }
public string EmailInfo { get; set; }
public List FusionCustomProperties { get; set; }
-
- public RoomInformation()
- {
- FusionCustomProperties = new List();
- }
}
+
public class FusionCustomProperty
{
- public string ID { get; set; }
- public string CustomFieldName { get; set; }
- public string CustomFieldType { get; set; }
- public string CustomFieldValue { get; set; }
-
public FusionCustomProperty()
{
-
}
public FusionCustomProperty(string id)
{
ID = id;
}
+
+ public string ID { get; set; }
+ public string CustomFieldName { get; set; }
+ public string CustomFieldType { get; set; }
+ public string CustomFieldValue { get; set; }
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs
new file mode 100644
index 00000000..33f2fe1b
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs
@@ -0,0 +1,150 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+
+using PepperDash.Essentials.Core.Bridges;
+
+
+namespace PepperDash.Essentials.Core.Fusion
+{
+ public class EssentialsHuddleSpaceRoomFusionRoomJoinMap : JoinMapBaseAdvanced
+ {
+
+ // Processor Attributes
+ [JoinName("ProcessorIp1")]
+ public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Info - Processor - IP 1" },
+ new JoinMetadata { Description = "Info - Processor - IP 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorIp2")]
+ public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1, AttributeName = "Info - Processor - IP 2" },
+ new JoinMetadata { Description = "Info - Processor - IP 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorGateway")]
+ public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1, AttributeName = "Info - Processor - Gateway" },
+ new JoinMetadata { Description = "Info - Processor - Gateway", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorHostname")]
+ public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1, AttributeName = "Info - Processor - Hostname" },
+ new JoinMetadata { Description = "Info - Processor - Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorDomain")]
+ public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 54, JoinSpan = 1, AttributeName = "Info - Processor - Domain" },
+ new JoinMetadata { Description = "Info - Processor - Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorDns1")]
+ public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - DNS 1" },
+ new JoinMetadata { Description = "Info - Processor - DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorDns2")]
+ public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1, AttributeName = "Info - Processor - DNS 2" },
+ new JoinMetadata { Description = "Info - Processor - DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorMac1")]
+ public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1, AttributeName = "Info - Processor - MAC 1" },
+ new JoinMetadata { Description = "Info - Processor - MAC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorMac2")]
+ public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1, AttributeName = "Info - Processor - MAC 2" },
+ new JoinMetadata { Description = "Info - Processor - MAC 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorNetMask1")]
+ public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 1" },
+ new JoinMetadata { Description = "Info - Processor - Net Mask 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorNetMask2")]
+ public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 2" },
+ new JoinMetadata { Description = "Info - Processor - Net Mask 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorFirmware")]
+ public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1, AttributeName = "Info - Processor - Firmware" },
+ new JoinMetadata { Description = "Info - Processor - Firmware", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProgramNameStart")]
+ public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10, AttributeName = "Info - Processor - Program" },
+ new JoinMetadata { Description = "Info - Processor - Program", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("ProcessorReboot")]
+ public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1, AttributeName = "Processor - Reboot" },
+ new JoinMetadata { Description = "Processor - Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital });
+
+ // Volume Controls
+ [JoinName("VolumeFader1")]
+ public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Volume - Fader01" },
+ new JoinMetadata { Description = "Volume - Fader01", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog });
+
+ // Codec Info
+ [JoinName("VcCodecInCall")]
+ public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1, AttributeName = "Conf - VC 1 In Call" },
+ new JoinMetadata { Description = "Conf - VC 1 In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
+
+ [JoinName("VcCodecOnline")]
+ public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1, AttributeName = "Online - VC 1" },
+ new JoinMetadata { Description = "Online - VC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
+
+ [JoinName("VcCodecIpAddress")]
+ public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1, AttributeName = "IP Address - VC" },
+ new JoinMetadata { Description = "IP Address - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ [JoinName("VcCodecIpPort")]
+ public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1, AttributeName = "IP Port - VC" },
+ new JoinMetadata { Description = "IP Port - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+ // Source Attributes
+ [JoinName("Display1CurrentSourceName")]
+ public JoinDataComplete Display1CurrentSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1, AttributeName = "Display 1 - Current Source" },
+ new JoinMetadata { Description = "Display 1 - Current Source", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+
+
+ // Device Online Status
+ [JoinName("TouchpanelOnlineStart")]
+ public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10, AttributeName = "Online - Touch Panel" },
+ new JoinMetadata { Description = "Online - Touch Panel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
+
+ [JoinName("XpanelOnlineStart")]
+ public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5, AttributeName = "Online - XPanel" },
+ new JoinMetadata { Description = "Online - XPanel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
+
+ [JoinName("DisplayOnlineStart")]
+ public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10, AttributeName = "Online - Display" },
+ new JoinMetadata { Description = "Online - Display", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
+
+ [JoinName("Display1LaptopSourceStart")]
+ public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 5, AttributeName = "Display 1 - Source Laptop" },
+ new JoinMetadata { Description = "Display 1 - Source Laptop", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
+
+ [JoinName("Display1DiscPlayerSourceStart")]
+ public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 181, JoinSpan = 5, AttributeName = "Display 1 - Source Disc Player" },
+ new JoinMetadata { Description = "Display 1 - Source Disc Player", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
+
+ [JoinName("Display1SetTopBoxSourceStart")]
+ public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5, AttributeName = "Display 1 - Source TV" },
+ new JoinMetadata { Description = "Display 1 - Source TV", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
+
+ // Display 1
+ [JoinName("Display1Start")]
+ public JoinDataComplete Display1Start = new JoinDataComplete(new JoinData { JoinNumber = 158, JoinSpan = 1 },
+ new JoinMetadata { Description = "Display 1 Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
+
+
+ ///
+ /// Constructor to use when instantiating this Join Map without inheriting from it
+ ///
+ /// Join this join map will start at
+ public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart)
+ : base(joinStart, typeof(EssentialsHuddleSpaceRoomFusionRoomJoinMap))
+ {
+
+ }
+
+ ///
+ /// Constructor to use when extending this Join map
+ ///
+ /// Join this join map will start at
+ /// Type of the child join map
+ public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart, Type type) : base(joinStart, type)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs
index a7b721ef..fb305172 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs
@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using Crestron.SimplSharp;
+using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharp.Scheduler;
using PepperDash.Core;
+using PepperDash.Essentials.Core.Fusion;
+using PepperDash.Essentials.Room.Config;
+using Activator = System.Activator;
namespace PepperDash.Essentials.Core
{
@@ -14,7 +17,7 @@ namespace PepperDash.Essentials.Core
///
public static class Scheduler
{
- private static Dictionary EventGroups = new Dictionary();
+ private static readonly Dictionary EventGroups = new Dictionary();
static Scheduler()
{
@@ -49,7 +52,6 @@ namespace PepperDash.Essentials.Core
///
/// Adds the event group to the global list
///
- ///
///
public static void AddEventGroup(ScheduledEventGroup eventGroup)
{
@@ -67,6 +69,13 @@ namespace PepperDash.Essentials.Core
if(!EventGroups.ContainsKey(eventGroup.Name))
EventGroups.Remove(eventGroup.Name);
}
+
+ public static ScheduledEventGroup GetEventGroup(string key)
+ {
+ ScheduledEventGroup returnValue;
+
+ return EventGroups.TryGetValue(key, out returnValue) ? returnValue : null;
+ }
}
public static class SchedulerUtilities
@@ -135,5 +144,90 @@ namespace PepperDash.Essentials.Core
return isMatch;
}
+
+ public static bool CheckEventTimeForMatch(ScheduledEvent evnt, DateTime time)
+ {
+ return evnt.DateAndTime.Hour == time.Hour && evnt.DateAndTime.Minute == time.Minute;
+ }
+
+ public static bool CheckEventRecurrenceForMatch(ScheduledEvent evnt, ScheduledEventCommon.eWeekDays days)
+ {
+ return evnt.Recurrence.RecurrenceDays == days;
+ }
+
+ public static void CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group, ScheduledEvent.UserEventCallBack handler)
+ {
+ if (group == null)
+ {
+ Debug.Console(0, "Unable to create event. Group is null");
+ return;
+ }
+ var scheduledEvent = new ScheduledEvent(config.Key, group)
+ {
+ Acknowledgeable = config.Acknowledgeable,
+ Persistent = config.Persistent
+ };
+
+ scheduledEvent.UserCallBack += handler;
+
+ scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday);
+
+ var eventTime = DateTime.Parse(config.Time);
+
+ if (DateTime.Now > eventTime)
+ {
+ eventTime = eventTime.AddDays(1);
+ }
+
+ Debug.Console(2, "[Scheduler] Current Date day of week: {0} recurrence days: {1}", eventTime.DayOfWeek,
+ config.Days);
+
+ var dayOfWeekConverted = ConvertDayOfWeek(eventTime);
+
+ Debug.Console(1, "[Scheduler] eventTime Day: {0}", dayOfWeekConverted);
+
+ while (!dayOfWeekConverted.IsFlagSet(config.Days))
+ {
+ eventTime = eventTime.AddDays(1);
+
+ dayOfWeekConverted = ConvertDayOfWeek(eventTime);
+ }
+
+ scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime);
+
+ scheduledEvent.Recurrence.Weekly(config.Days);
+
+ if (config.Enable)
+ {
+ scheduledEvent.Enable();
+ }
+ else
+ {
+ scheduledEvent.Disable();
+ }
+ }
+
+ private static ScheduledEventCommon.eWeekDays ConvertDayOfWeek(DateTime eventTime)
+ {
+ return (ScheduledEventCommon.eWeekDays) Enum.Parse(typeof(ScheduledEventCommon.eWeekDays), eventTime.DayOfWeek.ToString(), true);
+ }
+
+ private static bool IsFlagSet(this T value, T flag) where T : struct
+ {
+ CheckIsEnum(true);
+
+ var lValue = Convert.ToInt64(value);
+ var lFlag = Convert.ToInt64(flag);
+
+ return (lValue & lFlag) != 0;
+ }
+
+ private static void CheckIsEnum(bool withFlags)
+ {
+ if (!typeof(T).IsEnum)
+ throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName));
+ if (withFlags && !Attribute.IsDefined(typeof(T), typeof(FlagsAttribute)))
+ throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", typeof(T).FullName));
+ }
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs
new file mode 100644
index 00000000..92557319
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using PepperDash.Core;
+
+namespace PepperDash.Essentials.Core.Interfaces
+{
+ public interface ILogStrings : IKeyed
+ {
+ ///
+ /// Defines a class that is capable of logging a string
+ ///
+ void SendToLog(IKeyed device, string logMessage);
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs
new file mode 100644
index 00000000..c43c4e6c
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using PepperDash.Core;
+
+namespace PepperDash.Essentials.Core.Interfaces
+{
+ public interface ILogStringsWithLevel : IKeyed
+ {
+ ///
+ /// Defines a class that is capable of logging a string with an int level
+ ///
+ void SendToLog(IKeyed device, Debug.ErrorLogLevel level,string logMessage);
+ }
+
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs
index ad5df2e3..b9825749 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs
@@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Core
var joinMap = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
- return joinMap;
+ return joinMap.ToString();
}
///
@@ -45,16 +45,33 @@ namespace PepperDash.Essentials.Core
///
public static Dictionary TryGetJoinMapAdvancedForDevice(string joinMapKey)
{
- if (string.IsNullOrEmpty(joinMapKey))
+ try
+ {
+ if (string.IsNullOrEmpty(joinMapKey))
+ return null;
+
+ if (!ConfigReader.ConfigObject.JoinMaps.ContainsKey(joinMapKey))
+ {
+ Debug.Console(2, "No Join Map found in config with key: '{0}'", joinMapKey);
+ return null;
+ }
+
+ Debug.Console(2, "Attempting to load custom join map with key: {0}", joinMapKey);
+
+ var joinMapJToken = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
+
+ if (joinMapJToken == null)
+ return null;
+
+ var joinMapData = joinMapJToken.ToObject>();
+
+ return joinMapData;
+ }
+ catch (Exception e)
+ {
+ Debug.Console(2, "Error getting join map for key: '{0}'. Error: {1}", joinMapKey, e);
return null;
-
- var joinMapSerialzed = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
-
- if (joinMapSerialzed == null) return null;
-
- var joinMapData = JsonConvert.DeserializeObject>(joinMapSerialzed);
-
- return joinMapData;
+ }
}
}
@@ -266,7 +283,7 @@ namespace PepperDash.Essentials.Core
@"Join Number: {0} | JoinSpan: '{1}' | Description: '{2}' | Type: '{3}' | Capabilities: '{4}'",
join.Value.JoinNumber,
join.Value.JoinSpan,
- String.IsNullOrEmpty(join.Value.Metadata.Description) ? join.Value.Metadata.Label: join.Value.Metadata.Description,
+ String.IsNullOrEmpty(join.Value.AttributeName) ? join.Value.Metadata.Label : join.Value.AttributeName,
join.Value.Metadata.JoinType.ToString(),
join.Value.Metadata.JoinCapabilities.ToString());
}
@@ -288,7 +305,7 @@ namespace PepperDash.Essentials.Core
}
else
{
- Debug.Console(2, "No mathcing key found in join map for: '{0}'", customJoinData.Key);
+ Debug.Console(2, "No matching key found in join map for: '{0}'", customJoinData.Key);
}
}
@@ -327,7 +344,10 @@ namespace PepperDash.Essentials.Core
None = 0,
ToSIMPL = 1,
FromSIMPL = 2,
- ToFromSIMPL = ToSIMPL | FromSIMPL
+ ToFromSIMPL = ToSIMPL | FromSIMPL,
+ ToFusion = 4,
+ FromFusion = 8,
+ ToFromFusion = ToFusion | FromFusion,
}
[Flags]
@@ -340,7 +360,7 @@ namespace PepperDash.Essentials.Core
DigitalAnalog = Digital | Analog,
DigitalSerial = Digital | Serial,
AnalogSerial = Analog | Serial,
- DigitalAnalogSerial = Digital | Analog | Serial
+ DigitalAnalogSerial = Digital | Analog | Serial,
}
///
@@ -394,7 +414,7 @@ namespace PepperDash.Essentials.Core
}
///
- /// Data describing the join. Can be
+ /// Data describing the join. Can be overridden from configuratino
///
public class JoinData
{
@@ -408,6 +428,11 @@ namespace PepperDash.Essentials.Core
///
[JsonProperty("joinSpan")]
public uint JoinSpan { get; set; }
+ ///
+ /// Fusion Attribute Name (optional)
+ ///
+ [JsonProperty("attributeName")]
+ public string AttributeName { get; set; }
}
///
@@ -419,6 +444,10 @@ namespace PepperDash.Essentials.Core
private JoinData _data;
public JoinMetadata Metadata { get; set; }
+ ///
+ /// To store some future information as you please
+ ///
+ public object UserObject { get; private set; }
public JoinDataComplete(JoinData data, JoinMetadata metadata)
{
@@ -449,6 +478,11 @@ namespace PepperDash.Essentials.Core
get { return _data.JoinSpan; }
}
+ public string AttributeName
+ {
+ get { return _data.AttributeName; }
+ }
+
public void SetCustomJoinData(JoinData customJoinData)
{
_data = customJoinData;
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/StatusMonitorCollection.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/StatusMonitorCollection.cs
index d9b5b33a..7f985fe0 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/StatusMonitorCollection.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/StatusMonitorCollection.cs
@@ -64,30 +64,34 @@ namespace PepperDash.Essentials.Core
initialStatus = MonitorStatus.InWarning;
prefix = "2:";
}
- else if (InWarning.Count() > 0)
+ else if (IsOk.Count() > 0)
initialStatus = MonitorStatus.IsOk;
else
initialStatus = MonitorStatus.StatusUnknown;
// Build the error message string
- if (InError.Count() > 0 || InWarning.Count() > 0)
- {
- StringBuilder sb = new StringBuilder(prefix);
- if (InError.Count() > 0)
- {
- // Do string splits and joins
- sb.Append(string.Format("{0} Errors:", InError.Count()));
- foreach (var mon in InError)
- sb.Append(string.Format("{0}, ", mon.Parent.Key));
- }
- if (InWarning.Count() > 0)
- {
- sb.Append(string.Format("{0} Warnings:", InWarning.Count()));
- foreach (var mon in InWarning)
- sb.Append(string.Format("{0}, ", mon.Parent.Key));
- }
- Message = sb.ToString();
- }
+ if (InError.Count() > 0 || InWarning.Count() > 0)
+ {
+ StringBuilder sb = new StringBuilder(prefix);
+ if (InError.Count() > 0)
+ {
+ // Do string splits and joins
+ sb.Append(string.Format("{0} Errors:", InError.Count()));
+ foreach (var mon in InError)
+ sb.Append(string.Format("{0}, ", mon.Parent.Key));
+ }
+ if (InWarning.Count() > 0)
+ {
+ sb.Append(string.Format("{0} Warnings:", InWarning.Count()));
+ foreach (var mon in InWarning)
+ sb.Append(string.Format("{0}, ", mon.Parent.Key));
+ }
+ Message = sb.ToString();
+ }
+ else
+ {
+ Message = "Room Ok.";
+ }
// Want to fire even if status doesn't change because the message may.
Status = initialStatus;
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs
index eadaab12..ec18c995 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs
@@ -1,106 +1,106 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
-using Crestron.SimplSharp;
-using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.Diagnostics;
-using PepperDash.Core;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Converters;
-using PepperDash.Essentials.Core.Bridges;
-
-namespace PepperDash.Essentials.Core.Monitoring
-{
- ///
- /// Wrapper for the static SystemMonitor class to extend functionality and provide external access
- /// to SystemMonitor via APIs
- ///
- public class SystemMonitorController : EssentialsBridgeableDevice
- {
- private const long UptimePollTime = 300000;
- private CTimer _uptimePollTimer;
-
- private string _uptime;
- private string _lastStart;
-
- public event EventHandler SystemMonitorPropertiesChanged;
-
- public Dictionary ProgramStatusFeedbackCollection;
- public Dictionary EthernetStatusFeedbackCollection;
-
- public IntFeedback TimeZoneFeedback { get; protected set; }
- public StringFeedback TimeZoneTextFeedback { get; protected set; }
-
- public StringFeedback IoControllerVersionFeedback { get; protected set; }
- public StringFeedback SnmpVersionFeedback { get; protected set; }
- public StringFeedback BaCnetAppVersionFeedback { get; protected set; }
- public StringFeedback ControllerVersionFeedback { get; protected set; }
-
- //new feedbacks. Issue #50
- public StringFeedback SerialNumberFeedback { get; protected set; }
- public StringFeedback ModelFeedback { get; set; }
-
- public StringFeedback UptimeFeedback { get; set; }
- public StringFeedback LastStartFeedback { get; set; }
-
- public SystemMonitorController(string key)
- : base(key)
- {
- Debug.Console(2, this, "Adding SystemMonitorController.");
-
- SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
-
- TimeZoneFeedback = new IntFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneNumber);
- TimeZoneTextFeedback = new StringFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneName);
-
- IoControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.IOPVersion);
- SnmpVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.SNMPVersion);
- BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion);
- ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion);
-
- SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber);
- ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName);
- UptimeFeedback = new StringFeedback(() => _uptime);
- LastStartFeedback = new StringFeedback(()=> _lastStart);
-
- ProgramStatusFeedbackCollection = new Dictionary();
-
- foreach (var prog in SystemMonitor.ProgramCollection)
- {
- var program = new ProgramStatusFeedbacks(prog);
- ProgramStatusFeedbackCollection.Add(prog.Number, program);
- }
-
- CreateEthernetStatusFeedbacks();
- UpdateEthernetStatusFeeedbacks();
-
- _uptimePollTimer = new CTimer(PollUptime,null,0, UptimePollTime);
-
- SystemMonitor.ProgramChange += SystemMonitor_ProgramChange;
- SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange;
- CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler;
- CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironmentOnProgramStatusEventHandler;
- }
-
- private void CrestronEnvironmentOnProgramStatusEventHandler(eProgramStatusEventType programEventType)
- {
- if (programEventType != eProgramStatusEventType.Stopping) return;
-
- _uptimePollTimer.Stop();
- _uptimePollTimer.Dispose();
- _uptimePollTimer = null;
- }
-
- private void PollUptime(object obj)
- {
- var consoleResponse = string.Empty;
-
- CrestronConsole.SendControlSystemCommand("uptime", ref consoleResponse);
-
- ParseUptime(consoleResponse);
-
- UptimeFeedback.FireUpdate();
- LastStartFeedback.FireUpdate();
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.Diagnostics;
+using PepperDash.Core;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using PepperDash.Essentials.Core.Bridges;
+
+namespace PepperDash.Essentials.Core.Monitoring
+{
+ ///
+ /// Wrapper for the static SystemMonitor class to extend functionality and provide external access
+ /// to SystemMonitor via APIs
+ ///
+ public class SystemMonitorController : EssentialsBridgeableDevice
+ {
+ private const long UptimePollTime = 300000;
+ private CTimer _uptimePollTimer;
+
+ private string _uptime;
+ private string _lastStart;
+
+ public event EventHandler SystemMonitorPropertiesChanged;
+
+ public Dictionary ProgramStatusFeedbackCollection;
+ public Dictionary EthernetStatusFeedbackCollection;
+
+ public IntFeedback TimeZoneFeedback { get; protected set; }
+ public StringFeedback TimeZoneTextFeedback { get; protected set; }
+
+ public StringFeedback IoControllerVersionFeedback { get; protected set; }
+ public StringFeedback SnmpVersionFeedback { get; protected set; }
+ public StringFeedback BaCnetAppVersionFeedback { get; protected set; }
+ public StringFeedback ControllerVersionFeedback { get; protected set; }
+
+ //new feedbacks. Issue #50
+ public StringFeedback SerialNumberFeedback { get; protected set; }
+ public StringFeedback ModelFeedback { get; set; }
+
+ public StringFeedback UptimeFeedback { get; set; }
+ public StringFeedback LastStartFeedback { get; set; }
+
+ public SystemMonitorController(string key)
+ : base(key)
+ {
+ Debug.Console(2, this, "Adding SystemMonitorController.");
+
+ SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
+
+ TimeZoneFeedback = new IntFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneNumber);
+ TimeZoneTextFeedback = new StringFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneName);
+
+ IoControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.IOPVersion);
+ SnmpVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.SNMPVersion);
+ BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion);
+ ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion);
+
+ SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber);
+ ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName);
+ UptimeFeedback = new StringFeedback(() => _uptime);
+ LastStartFeedback = new StringFeedback(()=> _lastStart);
+
+ ProgramStatusFeedbackCollection = new Dictionary();
+
+ foreach (var prog in SystemMonitor.ProgramCollection)
+ {
+ var program = new ProgramStatusFeedbacks(prog);
+ ProgramStatusFeedbackCollection.Add(prog.Number, program);
+ }
+
+ CreateEthernetStatusFeedbacks();
+ UpdateEthernetStatusFeeedbacks();
+
+ _uptimePollTimer = new CTimer(PollUptime,null,0, UptimePollTime);
+
+ SystemMonitor.ProgramChange += SystemMonitor_ProgramChange;
+ SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange;
+ CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler;
+ CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironmentOnProgramStatusEventHandler;
+ }
+
+ private void CrestronEnvironmentOnProgramStatusEventHandler(eProgramStatusEventType programEventType)
+ {
+ if (programEventType != eProgramStatusEventType.Stopping) return;
+
+ _uptimePollTimer.Stop();
+ _uptimePollTimer.Dispose();
+ _uptimePollTimer = null;
+ }
+
+ private void PollUptime(object obj)
+ {
+ var consoleResponse = string.Empty;
+
+ CrestronConsole.SendControlSystemCommand("uptime", ref consoleResponse);
+
+ ParseUptime(consoleResponse);
+
+ UptimeFeedback.FireUpdate();
+ LastStartFeedback.FireUpdate();
}
private void ParseUptime(string response)
@@ -123,94 +123,94 @@ namespace PepperDash.Essentials.Core.Monitoring
_uptime = uptimeRaw.Substring(forIndex + 4);
}
- private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs)
- {
- if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return;
-
- foreach (var fb in EthernetStatusFeedbackCollection)
- {
- fb.Value.UpdateEthernetStatus();
- }
- }
-
- private void CreateEthernetStatusFeedbacks()
- {
- EthernetStatusFeedbackCollection = new Dictionary();
-
- Debug.Console(2, "Creating {0} EthernetStatusFeedbacks", InitialParametersClass.NumberOfEthernetInterfaces);
-
- for (short i = 0; i < InitialParametersClass.NumberOfEthernetInterfaces; i++)
- {
- Debug.Console(2, "Creating EthernetStatusFeedback for Interface {0}", i);
- var ethernetInterface = new EthernetStatusFeedbacks(i);
- EthernetStatusFeedbackCollection.Add(i, ethernetInterface);
- }
- }
-
- private void UpdateEthernetStatusFeeedbacks()
- {
- foreach (var iface in EthernetStatusFeedbackCollection)
- {
- iface.Value.CurrentIpAddressFeedback.FireUpdate();
- iface.Value.CurrentSubnetMaskFeedback.FireUpdate();
- iface.Value.CurrentDefaultGatewayFeedback.FireUpdate();
- iface.Value.StaticIpAddressFeedback.FireUpdate();
- iface.Value.StaticSubnetMaskFeedback.FireUpdate();
- iface.Value.StaticDefaultGatewayFeedback.FireUpdate();
- iface.Value.HostNameFeedback.FireUpdate();
- iface.Value.DnsServerFeedback.FireUpdate();
- iface.Value.DomainFeedback.FireUpdate();
- iface.Value.DhcpStatusFeedback.FireUpdate();
- iface.Value.MacAddressFeedback.FireUpdate();
- }
- }
-
- ///
- /// Gets data in separate thread
- ///
- private void RefreshSystemMonitorData()
- {
- // this takes a while, launch a new thread
- CrestronInvoke.BeginInvoke(UpdateFeedback);
- }
-
- private void UpdateFeedback(object o)
- {
- TimeZoneFeedback.FireUpdate();
- TimeZoneTextFeedback.FireUpdate();
- IoControllerVersionFeedback.FireUpdate();
- SnmpVersionFeedback.FireUpdate();
- BaCnetAppVersionFeedback.FireUpdate();
- ControllerVersionFeedback.FireUpdate();
- SerialNumberFeedback.FireUpdate();
- ModelFeedback.FireUpdate();
-
- OnSystemMonitorPropertiesChanged();
- }
-
- private void OnSystemMonitorPropertiesChanged()
- {
- var handler = SystemMonitorPropertiesChanged;
- if (handler != null)
- {
- handler(this, new EventArgs());
- }
- }
-
- public override bool CustomActivate()
- {
- RefreshSystemMonitorData();
-
- return base.CustomActivate();
- }
-
- public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs)
{
- var joinMap = new SystemMonitorJoinMap(joinStart);
-
- var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
-
- if (!string.IsNullOrEmpty(joinMapSerialized))
+ if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return;
+
+ foreach (var fb in EthernetStatusFeedbackCollection)
+ {
+ fb.Value.UpdateEthernetStatus();
+ }
+ }
+
+ private void CreateEthernetStatusFeedbacks()
+ {
+ EthernetStatusFeedbackCollection = new Dictionary();
+
+ Debug.Console(2, "Creating {0} EthernetStatusFeedbacks", InitialParametersClass.NumberOfEthernetInterfaces);
+
+ for (short i = 0; i < InitialParametersClass.NumberOfEthernetInterfaces; i++)
+ {
+ Debug.Console(2, "Creating EthernetStatusFeedback for Interface {0}", i);
+ var ethernetInterface = new EthernetStatusFeedbacks(i);
+ EthernetStatusFeedbackCollection.Add(i, ethernetInterface);
+ }
+ }
+
+ private void UpdateEthernetStatusFeeedbacks()
+ {
+ foreach (var iface in EthernetStatusFeedbackCollection)
+ {
+ iface.Value.CurrentIpAddressFeedback.FireUpdate();
+ iface.Value.CurrentSubnetMaskFeedback.FireUpdate();
+ iface.Value.CurrentDefaultGatewayFeedback.FireUpdate();
+ iface.Value.StaticIpAddressFeedback.FireUpdate();
+ iface.Value.StaticSubnetMaskFeedback.FireUpdate();
+ iface.Value.StaticDefaultGatewayFeedback.FireUpdate();
+ iface.Value.HostNameFeedback.FireUpdate();
+ iface.Value.DnsServerFeedback.FireUpdate();
+ iface.Value.DomainFeedback.FireUpdate();
+ iface.Value.DhcpStatusFeedback.FireUpdate();
+ iface.Value.MacAddressFeedback.FireUpdate();
+ }
+ }
+
+ ///
+ /// Gets data in separate thread
+ ///
+ private void RefreshSystemMonitorData()
+ {
+ // this takes a while, launch a new thread
+ CrestronInvoke.BeginInvoke(UpdateFeedback);
+ }
+
+ private void UpdateFeedback(object o)
+ {
+ TimeZoneFeedback.FireUpdate();
+ TimeZoneTextFeedback.FireUpdate();
+ IoControllerVersionFeedback.FireUpdate();
+ SnmpVersionFeedback.FireUpdate();
+ BaCnetAppVersionFeedback.FireUpdate();
+ ControllerVersionFeedback.FireUpdate();
+ SerialNumberFeedback.FireUpdate();
+ ModelFeedback.FireUpdate();
+
+ OnSystemMonitorPropertiesChanged();
+ }
+
+ private void OnSystemMonitorPropertiesChanged()
+ {
+ var handler = SystemMonitorPropertiesChanged;
+ if (handler != null)
+ {
+ handler(this, new EventArgs());
+ }
+ }
+
+ public override bool CustomActivate()
+ {
+ RefreshSystemMonitorData();
+
+ return base.CustomActivate();
+ }
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = new SystemMonitorJoinMap(joinStart);
+
+ var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
+
+ if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject(joinMapSerialized);
if (bridge != null)
@@ -220,11 +220,11 @@ namespace PepperDash.Essentials.Core.Monitoring
else
{
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
- }
-
- Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
- Debug.Console(2, this, "Linking API starting at join: {0}", joinStart);
-
+ }
+
+ Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+ Debug.Console(2, this, "Linking API starting at join: {0}", joinStart);
+
TimeZoneFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeZone.JoinNumber]);
TimeZoneTextFeedback.LinkInputSig(trilist.StringInput[joinMap.TimeZoneName.JoinNumber]);
@@ -235,18 +235,18 @@ namespace PepperDash.Essentials.Core.Monitoring
SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumber.JoinNumber]);
ModelFeedback.LinkInputSig(trilist.StringInput[joinMap.Model.JoinNumber]);
UptimeFeedback.LinkInputSig(trilist.StringInput[joinMap.Uptime.JoinNumber]);
- LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot.JoinNumber]);
-
- // iterate the program status feedback collection and map all the joins
- LinkProgramInfoJoins(this, trilist, joinMap);
-
- LinkEthernetInfoJoins(this, trilist, joinMap);
- }
-
- private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap)
+ LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot.JoinNumber]);
+
+ // iterate the program status feedback collection and map all the joins
+ LinkProgramInfoJoins(this, trilist, joinMap);
+
+ LinkEthernetInfoJoins(this, trilist, joinMap);
+ }
+
+ private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap)
{
- uint ethernetSlotJoinStart = 0;
- foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection)
+ uint ethernetSlotJoinStart = 0;
+ foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection)
{
fb.Value.CurrentIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentIpAddress.JoinNumber]);
fb.Value.CurrentSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentSubnetMask.JoinNumber]);
@@ -258,494 +258,500 @@ namespace PepperDash.Essentials.Core.Monitoring
fb.Value.MacAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.MacAddress.JoinNumber]);
fb.Value.DomainFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.Domain.JoinNumber]);
fb.Value.DnsServerFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DnsServer.JoinNumber]);
- fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus.JoinNumber]);
-
- ethernetSlotJoinStart += joinMap.EthernetOffsetJoin.JoinNumber;
- }
- }
-
- private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist,
- SystemMonitorJoinMap joinMap)
+ fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus.JoinNumber]);
+
+ ethernetSlotJoinStart += joinMap.EthernetOffsetJoin.JoinNumber;
+ }
+ }
+
+ private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist,
+ SystemMonitorJoinMap joinMap)
{
- uint programSlotJoinStart = 0;
-
- foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection)
- {
+ uint programSlotJoinStart = 0;
+
+ foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection)
+ {
var programNumber = p.Value.Program.Number;
- trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart.JoinNumber,
+ trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart.JoinNumber,
b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start);
p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart.JoinNumber]);
- trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop.JoinNumber,
+ trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop.JoinNumber,
b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop);
p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop.JoinNumber]);
- trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister.JoinNumber,
- b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register);
+ trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister.JoinNumber,
+ b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register);
p.Value.ProgramRegisteredFeedback.LinkInputSig(
trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister.JoinNumber]);
- trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister.JoinNumber,
- b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister);
+ trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister.JoinNumber,
+ b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister);
p.Value.ProgramUnregisteredFeedback.LinkInputSig(
trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister.JoinNumber]);
- p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName.JoinNumber]);
+ p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName.JoinNumber]);
p.Value.ProgramCompileTimeFeedback.LinkInputSig(
- trilist.StringInput[programSlotJoinStart + joinMap.ProgramCompiledTime.JoinNumber]);
+ trilist.StringInput[programSlotJoinStart + joinMap.ProgramCompiledTime.JoinNumber]);
p.Value.CrestronDataBaseVersionFeedback.LinkInputSig(
- trilist.StringInput[programSlotJoinStart + joinMap.ProgramCrestronDatabaseVersion.JoinNumber]);
+ trilist.StringInput[programSlotJoinStart + joinMap.ProgramCrestronDatabaseVersion.JoinNumber]);
p.Value.EnvironmentVersionFeedback.LinkInputSig(
- trilist.StringInput[programSlotJoinStart + joinMap.ProgramEnvironmentVersion.JoinNumber]);
+ trilist.StringInput[programSlotJoinStart + joinMap.ProgramEnvironmentVersion.JoinNumber]);
p.Value.AggregatedProgramInfoFeedback.LinkInputSig(
trilist.StringInput[programSlotJoinStart + joinMap.AggregatedProgramInfo.JoinNumber]);
- programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin.JoinNumber;
- }
- }
-
- //// Sets the time zone
- //public void SetTimeZone(int timeZone)
- //{
- // SystemMonitor.TimeZoneInformation.TimeZoneNumber = timeZone;
- //}
-
- ///
- /// Responds to program change events and triggers the appropriate feedbacks to update
- ///
- ///
- ///
- private void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args)
- {
- Debug.Console(2, this, "Program Change Detected for slot: {0}", sender.Number);
- Debug.Console(2, this, "Event Type: {0}", args.EventType);
-
- var program = ProgramStatusFeedbackCollection[sender.Number];
-
- switch (args.EventType)
- {
- case eProgramChangeEventType.OperatingState:
- program.ProgramStartedFeedback.FireUpdate();
- program.ProgramStoppedFeedback.FireUpdate();
- program.ProgramInfo.OperatingState = args.OperatingState;
- if (args.OperatingState == eProgramOperatingState.Start)
- program.GetProgramInfo();
- else
- {
- program.AggregatedProgramInfoFeedback.FireUpdate();
- program.OnProgramInfoChanged();
- }
- break;
- case eProgramChangeEventType.RegistrationState:
- program.ProgramRegisteredFeedback.FireUpdate();
- program.ProgramUnregisteredFeedback.FireUpdate();
- program.ProgramInfo.RegistrationState = args.RegistrationState;
- program.GetProgramInfo();
- break;
- }
- }
-
- ///
- /// Responds to time zone changes and updates the appropriate feedbacks
- ///
- ///
- private void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args)
- {
- Debug.Console(2, this, "Time Zone Change Detected.");
- TimeZoneFeedback.FireUpdate();
- TimeZoneTextFeedback.FireUpdate();
-
- OnSystemMonitorPropertiesChanged();
- }
-
- public class EthernetStatusFeedbacks
- {
- public StringFeedback HostNameFeedback { get; protected set; }
- public StringFeedback DnsServerFeedback { get; protected set; }
- public StringFeedback DomainFeedback { get; protected set; }
- public StringFeedback MacAddressFeedback { get; protected set; }
- public StringFeedback DhcpStatusFeedback { get; protected set; }
-
- public StringFeedback CurrentIpAddressFeedback { get; protected set; }
- public StringFeedback CurrentSubnetMaskFeedback { get; protected set; }
- public StringFeedback CurrentDefaultGatewayFeedback { get; protected set; }
-
- public StringFeedback StaticIpAddressFeedback { get; protected set; }
- public StringFeedback StaticSubnetMaskFeedback { get; protected set; }
- public StringFeedback StaticDefaultGatewayFeedback { get; protected set; }
-
- public EthernetStatusFeedbacks(short adapterIndex)
- {
- Debug.Console(2, "Ethernet Information for interface {0}", adapterIndex);
- Debug.Console(2, "Adapter Index: {1} Hostname: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex), adapterIndex);
- Debug.Console(2, "Adapter Index: {1} Current IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex), adapterIndex);
- Debug.Console(2, "Adapter Index: {1} Current Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex), adapterIndex);
- Debug.Console(2, "Adapter Index: {1} Current Router: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex), adapterIndex);
- Debug.Console(2, "Adapter Index: {1} Static IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPADDRESS, adapterIndex), adapterIndex);
- Debug.Console(2, "Adapter Index: {1} Static Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPMASK, adapterIndex), adapterIndex);
- Debug.Console(2, "Adapter Index: {1} Static Router: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_ROUTER, adapterIndex), adapterIndex);
- Debug.Console(2, "Adapter Index: {1} DNS Servers: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex), adapterIndex);
- Debug.Console(2, "Adapter Index: {1} DHCP State: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex), adapterIndex);
- Debug.Console(2, "Adapter Index: {1} Domain Name: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex), adapterIndex);
- Debug.Console(2, "Adapter Index: {1} MAC Address: {0}", CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex), adapterIndex);
- HostNameFeedback =
- new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex));
-
- CurrentIpAddressFeedback =
- new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex));
- CurrentDefaultGatewayFeedback =
- new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex));
- CurrentSubnetMaskFeedback =
- new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex));
- StaticIpAddressFeedback =
- new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex));
- StaticDefaultGatewayFeedback =
- new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex));
- StaticSubnetMaskFeedback =
- new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex));
- DomainFeedback =
- new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex));
- DnsServerFeedback =
- new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex));
- MacAddressFeedback =
- new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex));
-
- DhcpStatusFeedback = new StringFeedback(
- () =>
- CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex));
- }
-
- public void UpdateEthernetStatus()
- {
- HostNameFeedback.FireUpdate();
- CurrentIpAddressFeedback.FireUpdate();
- CurrentSubnetMaskFeedback.FireUpdate();
- CurrentDefaultGatewayFeedback.FireUpdate();
- StaticIpAddressFeedback.FireUpdate();
- StaticSubnetMaskFeedback.FireUpdate();
- StaticDefaultGatewayFeedback.FireUpdate();
- DomainFeedback.FireUpdate();
- DnsServerFeedback.FireUpdate();
- MacAddressFeedback.FireUpdate();
- DhcpStatusFeedback.FireUpdate();
- }
- }
-
-
- public class ProgramStatusFeedbacks
- {
- public event EventHandler ProgramInfoChanged;
-
- public Program Program;
-
- public ProgramInfo ProgramInfo { get; set; }
-
- public BoolFeedback ProgramStartedFeedback;
- public BoolFeedback ProgramStoppedFeedback;
- public BoolFeedback ProgramRegisteredFeedback;
- public BoolFeedback ProgramUnregisteredFeedback;
-
- public StringFeedback ProgramNameFeedback;
- public StringFeedback ProgramCompileTimeFeedback;
- public StringFeedback CrestronDataBaseVersionFeedback;
- // SIMPL windows version
- public StringFeedback EnvironmentVersionFeedback;
- public StringFeedback AggregatedProgramInfoFeedback;
-
- public ProgramStatusFeedbacks(Program program)
- {
- ProgramInfo = new ProgramInfo(program.Number);
-
- Program = program;
-
- ProgramInfo.OperatingState = Program.OperatingState;
- ProgramInfo.RegistrationState = Program.RegistrationState;
-
- ProgramStartedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Start);
- ProgramStoppedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Stop);
- ProgramRegisteredFeedback =
- new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Register);
- ProgramUnregisteredFeedback =
- new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister);
-
- ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile);
- ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime);
- CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb);
- EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment);
-
- AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo));
-
- GetProgramInfo();
- }
-
- ///
- /// Retrieves information about a running program
- ///
- public void GetProgramInfo()
- {
- CrestronInvoke.BeginInvoke(GetProgramInfo);
- }
-
- private void GetProgramInfo(object o)
- {
- Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number);
-
- string response = null;
-
- if (Program.RegistrationState == eProgramRegistrationState.Unregister || Program.OperatingState == eProgramOperatingState.Stop)
- {
- Debug.Console(2, "Program {0} not registered. Setting default values for program information.",
- Program.Number);
-
- ProgramInfo = new ProgramInfo(Program.Number)
- {
- OperatingState = Program.OperatingState,
- RegistrationState = Program.RegistrationState
- };
-
- return;
- }
-
- var success = CrestronConsole.SendControlSystemCommand(
- string.Format("progcomments:{0}", Program.Number), ref response);
-
- if (!success)
- {
- Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number);
- UpdateFeedbacks();
- return;
- }
-
- if (response.ToLower().Contains("bad or incomplete"))
- {
- Debug.Console(2,
- "Program in slot {0} not running. Setting default ProgramInfo for slot: {0}",
- Program.Number);
-
- // Assume no valid program info. Constructing a new object will wipe all properties
- ProgramInfo = new ProgramInfo(Program.Number)
- {
- OperatingState = Program.OperatingState,
- RegistrationState = Program.RegistrationState
- };
-
- UpdateFeedbacks();
-
- return;
- }
-
-
- // Shared properteis
- ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n");
- ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n");
- ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n");
- ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n");
-
-
- if (ProgramInfo.ProgramFile.Contains(".dll"))
- {
- // SSP Program
- ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n");
- ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n");
- ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n");
- ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ",
- "\n");
- ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n");
- }
- else if (ProgramInfo.ProgramFile.Contains(".smw"))
- {
- // SIMPL Windows Program
- ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n");
- ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n");
- ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n");
- ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n");
- ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n");
- }
- Debug.Console(2, "Program info for slot {0} successfully updated", Program.Number);
-
- UpdateFeedbacks();
- }
-
- private void UpdateFeedbacks()
- {
- ProgramNameFeedback.FireUpdate();
- ProgramCompileTimeFeedback.FireUpdate();
- CrestronDataBaseVersionFeedback.FireUpdate();
- EnvironmentVersionFeedback.FireUpdate();
-
- AggregatedProgramInfoFeedback.FireUpdate();
-
- OnProgramInfoChanged();
- }
-
- public void OnProgramInfoChanged()
- {
- //Debug.Console(1, "Firing ProgramInfoChanged for slot: {0}", Program.Number);
- var handler = ProgramInfoChanged;
- if (handler != null)
- {
- handler(this, new ProgramInfoEventArgs(ProgramInfo));
- }
- }
-
- private string ParseConsoleData(string data, string line, string startString, string endString)
- {
- var outputData = "";
-
- if (data.Length <= 0) return outputData;
-
- try
- {
- //Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString);
- var linePosition = data.IndexOf(line, StringComparison.Ordinal);
- var startPosition = data.IndexOf(startString, linePosition, StringComparison.Ordinal) +
- startString.Length;
- var endPosition = data.IndexOf(endString, startPosition, StringComparison.Ordinal);
- outputData = data.Substring(startPosition, endPosition - startPosition).Trim();
- //Debug.Console(2, "ParseConsoleData Return: {0}", outputData);
- }
- catch (Exception e)
- {
- Debug.Console(1, "Error Parsing Console Data:\r{0}", e);
- }
-
- return outputData;
- }
- }
- }
-
- ///
- /// Class for serializing program slot information
- ///
- public class ProgramInfo
- {
- // Shared properties
-
- [JsonProperty("programNumber")]
- public uint ProgramNumber { get; private set; }
-
- [JsonConverter(typeof (StringEnumConverter))]
- [JsonProperty("operatingState")]
- public eProgramOperatingState OperatingState { get; set; }
-
- [JsonConverter(typeof (StringEnumConverter))]
- [JsonProperty("registrationState")]
- public eProgramRegistrationState RegistrationState { get; set; }
-
- [JsonProperty("programFile")]
- public string ProgramFile { get; set; }
-
- [JsonProperty("friendlyName")]
- public string FriendlyName { get; set; }
-
- [JsonProperty("compilerRevision")]
- public string CompilerRevision { get; set; }
-
- [JsonProperty("compileTime")]
- public string CompileTime { get; set; }
-
- [JsonProperty("include4Dat")]
- public string Include4Dat { get; set; }
-
- // SIMPL Windows properties
- [JsonProperty("systemName")]
- public string SystemName { get; set; }
-
- [JsonProperty("crestronDb")]
- public string CrestronDb { get; set; }
-
- [JsonProperty("environment")]
- public string Environment { get; set; }
-
- [JsonProperty("programmer")]
- public string Programmer { get; set; }
-
-
- // SSP Properties
- [JsonProperty("applicationName")]
- public string ApplicationName { get; set; }
-
- [JsonProperty("programTool")]
- public string ProgramTool { get; set; }
-
- [JsonProperty("minFirmwareVersion")]
- public string MinFirmwareVersion { get; set; }
-
- [JsonProperty("plugInVersion")]
- public string PlugInVersion { get; set; }
-
- public ProgramInfo(uint number)
- {
- ProgramNumber = number;
-
- ProgramFile = "";
- FriendlyName = "";
- CompilerRevision = "";
- CompileTime = "";
- Include4Dat = "";
-
- SystemName = "";
- CrestronDb = "";
- Environment = "";
- Programmer = "";
-
- ApplicationName = "";
- ProgramTool = "";
- MinFirmwareVersion = "";
- PlugInVersion = "";
- }
- }
-
- public class ProgramInfoEventArgs : EventArgs
- {
- public ProgramInfo ProgramInfo;
-
- public ProgramInfoEventArgs(ProgramInfo progInfo)
- {
- ProgramInfo = progInfo;
- }
- }
+ programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin.JoinNumber;
+ }
+ }
+
+ //// Sets the time zone
+ //public void SetTimeZone(int timeZone)
+ //{
+ // SystemMonitor.TimeZoneInformation.TimeZoneNumber = timeZone;
+ //}
+
+ ///
+ /// Responds to program change events and triggers the appropriate feedbacks to update
+ ///
+ ///
+ ///
+ private void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args)
+ {
+ Debug.Console(2, this, "Program Change Detected for slot: {0}", sender.Number);
+ Debug.Console(2, this, "Event Type: {0}", args.EventType);
+
+ var program = ProgramStatusFeedbackCollection[sender.Number];
+
+ switch (args.EventType)
+ {
+ case eProgramChangeEventType.OperatingState:
+ program.ProgramStartedFeedback.FireUpdate();
+ program.ProgramStoppedFeedback.FireUpdate();
+ program.ProgramInfo.OperatingState = args.OperatingState;
+ if (args.OperatingState == eProgramOperatingState.Start)
+ program.GetProgramInfo();
+ else
+ {
+ program.AggregatedProgramInfoFeedback.FireUpdate();
+ program.OnProgramInfoChanged();
+ }
+ break;
+ case eProgramChangeEventType.RegistrationState:
+ program.ProgramRegisteredFeedback.FireUpdate();
+ program.ProgramUnregisteredFeedback.FireUpdate();
+ program.ProgramInfo.RegistrationState = args.RegistrationState;
+ program.GetProgramInfo();
+ break;
+ }
+ }
+
+ ///
+ /// Responds to time zone changes and updates the appropriate feedbacks
+ ///
+ ///
+ private void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args)
+ {
+ Debug.Console(2, this, "Time Zone Change Detected.");
+ TimeZoneFeedback.FireUpdate();
+ TimeZoneTextFeedback.FireUpdate();
+
+ OnSystemMonitorPropertiesChanged();
+ }
+
+ public class EthernetStatusFeedbacks
+ {
+ public StringFeedback HostNameFeedback { get; protected set; }
+ public StringFeedback DnsServerFeedback { get; protected set; }
+ public StringFeedback DomainFeedback { get; protected set; }
+ public StringFeedback MacAddressFeedback { get; protected set; }
+ public StringFeedback DhcpStatusFeedback { get; protected set; }
+
+ public StringFeedback CurrentIpAddressFeedback { get; protected set; }
+ public StringFeedback CurrentSubnetMaskFeedback { get; protected set; }
+ public StringFeedback CurrentDefaultGatewayFeedback { get; protected set; }
+
+ public StringFeedback StaticIpAddressFeedback { get; protected set; }
+ public StringFeedback StaticSubnetMaskFeedback { get; protected set; }
+ public StringFeedback StaticDefaultGatewayFeedback { get; protected set; }
+
+ public EthernetStatusFeedbacks(short adapterIndex)
+ {
+ Debug.Console(2, "Ethernet Information for interface {0}", adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} Hostname: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex), adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} Current IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex), adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} Current Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex), adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} Current Router: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex), adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} Static IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPADDRESS, adapterIndex), adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} Static Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPMASK, adapterIndex), adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} Static Router: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_ROUTER, adapterIndex), adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} DNS Servers: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex), adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} DHCP State: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex), adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} Domain Name: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex), adapterIndex);
+ Debug.Console(2, "Adapter Index: {1} MAC Address: {0}", CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex), adapterIndex);
+ HostNameFeedback =
+ new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex));
+
+ CurrentIpAddressFeedback =
+ new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex));
+ CurrentDefaultGatewayFeedback =
+ new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex));
+ CurrentSubnetMaskFeedback =
+ new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex));
+ StaticIpAddressFeedback =
+ new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex));
+ StaticDefaultGatewayFeedback =
+ new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex));
+ StaticSubnetMaskFeedback =
+ new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex));
+ DomainFeedback =
+ new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex));
+ DnsServerFeedback =
+ new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex));
+ MacAddressFeedback =
+ new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex));
+
+ DhcpStatusFeedback = new StringFeedback(
+ () =>
+ CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex));
+ }
+
+ public void UpdateEthernetStatus()
+ {
+ HostNameFeedback.FireUpdate();
+ CurrentIpAddressFeedback.FireUpdate();
+ CurrentSubnetMaskFeedback.FireUpdate();
+ CurrentDefaultGatewayFeedback.FireUpdate();
+ StaticIpAddressFeedback.FireUpdate();
+ StaticSubnetMaskFeedback.FireUpdate();
+ StaticDefaultGatewayFeedback.FireUpdate();
+ DomainFeedback.FireUpdate();
+ DnsServerFeedback.FireUpdate();
+ MacAddressFeedback.FireUpdate();
+ DhcpStatusFeedback.FireUpdate();
+ }
+ }
+
+
+ public class ProgramStatusFeedbacks
+ {
+ public event EventHandler ProgramInfoChanged;
+
+ public Program Program;
+
+ public ProgramInfo ProgramInfo { get; set; }
+
+ public BoolFeedback ProgramStartedFeedback;
+ public BoolFeedback ProgramStoppedFeedback;
+ public BoolFeedback ProgramRegisteredFeedback;
+ public BoolFeedback ProgramUnregisteredFeedback;
+
+ public StringFeedback ProgramNameFeedback;
+ public StringFeedback ProgramCompileTimeFeedback;
+ public StringFeedback CrestronDataBaseVersionFeedback;
+ // SIMPL windows version
+ public StringFeedback EnvironmentVersionFeedback;
+ public StringFeedback AggregatedProgramInfoFeedback;
+
+ public ProgramStatusFeedbacks(Program program)
+ {
+ ProgramInfo = new ProgramInfo(program.Number);
+
+ Program = program;
+
+ ProgramInfo.OperatingState = Program.OperatingState;
+ ProgramInfo.RegistrationState = Program.RegistrationState;
+
+ ProgramStartedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Start);
+ ProgramStartedFeedback.FireUpdate();
+
+ ProgramStoppedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Stop);
+ ProgramStoppedFeedback.FireUpdate();
+
+ ProgramRegisteredFeedback =
+ new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Register);
+ ProgramRegisteredFeedback.FireUpdate();
+
+ ProgramUnregisteredFeedback =
+ new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister);
+ ProgramUnregisteredFeedback.FireUpdate();
+
+ ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile);
+ ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime);
+ CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb);
+ EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment);
+ AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo));
+
+ GetProgramInfo();
+ }
+
+ ///
+ /// Retrieves information about a running program
+ ///
+ public void GetProgramInfo()
+ {
+ CrestronInvoke.BeginInvoke(GetProgramInfo);
+ }
+
+ private void GetProgramInfo(object o)
+ {
+ Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number);
+
+ string response = null;
+
+ if (Program.RegistrationState == eProgramRegistrationState.Unregister || Program.OperatingState == eProgramOperatingState.Stop)
+ {
+ Debug.Console(2, "Program {0} not registered. Setting default values for program information.",
+ Program.Number);
+
+ ProgramInfo = new ProgramInfo(Program.Number)
+ {
+ OperatingState = Program.OperatingState,
+ RegistrationState = Program.RegistrationState
+ };
+
+ return;
+ }
+
+ var success = CrestronConsole.SendControlSystemCommand(
+ string.Format("progcomments:{0}", Program.Number), ref response);
+
+ if (!success)
+ {
+ Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number);
+ UpdateFeedbacks();
+ return;
+ }
+
+ if (response.ToLower().Contains("bad or incomplete"))
+ {
+ Debug.Console(2,
+ "Program in slot {0} not running. Setting default ProgramInfo for slot: {0}",
+ Program.Number);
+
+ // Assume no valid program info. Constructing a new object will wipe all properties
+ ProgramInfo = new ProgramInfo(Program.Number)
+ {
+ OperatingState = Program.OperatingState,
+ RegistrationState = Program.RegistrationState
+ };
+
+ UpdateFeedbacks();
+
+ return;
+ }
+
+
+ // Shared properteis
+ ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n");
+ ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n");
+ ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n");
+ ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n");
+
+
+ if (ProgramInfo.ProgramFile.Contains(".dll"))
+ {
+ // SSP Program
+ ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n");
+ ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n");
+ ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n");
+ ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ",
+ "\n");
+ ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n");
+ }
+ else if (ProgramInfo.ProgramFile.Contains(".smw"))
+ {
+ // SIMPL Windows Program
+ ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n");
+ ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n");
+ ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n");
+ ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n");
+ ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n");
+ }
+ Debug.Console(2, "Program info for slot {0} successfully updated", Program.Number);
+
+ UpdateFeedbacks();
+ }
+
+ private void UpdateFeedbacks()
+ {
+ ProgramNameFeedback.FireUpdate();
+ ProgramCompileTimeFeedback.FireUpdate();
+ CrestronDataBaseVersionFeedback.FireUpdate();
+ EnvironmentVersionFeedback.FireUpdate();
+
+ AggregatedProgramInfoFeedback.FireUpdate();
+
+ OnProgramInfoChanged();
+ }
+
+ public void OnProgramInfoChanged()
+ {
+ //Debug.Console(1, "Firing ProgramInfoChanged for slot: {0}", Program.Number);
+ var handler = ProgramInfoChanged;
+ if (handler != null)
+ {
+ handler(this, new ProgramInfoEventArgs(ProgramInfo));
+ }
+ }
+
+ private string ParseConsoleData(string data, string line, string startString, string endString)
+ {
+ var outputData = "";
+
+ if (data.Length <= 0) return outputData;
+
+ try
+ {
+ //Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString);
+ var linePosition = data.IndexOf(line, StringComparison.Ordinal);
+ var startPosition = data.IndexOf(startString, linePosition, StringComparison.Ordinal) +
+ startString.Length;
+ var endPosition = data.IndexOf(endString, startPosition, StringComparison.Ordinal);
+ outputData = data.Substring(startPosition, endPosition - startPosition).Trim();
+ //Debug.Console(2, "ParseConsoleData Return: {0}", outputData);
+ }
+ catch (Exception e)
+ {
+ Debug.Console(1, "Error Parsing Console Data:\r{0}", e);
+ }
+
+ return outputData;
+ }
+ }
+ }
+
+ ///
+ /// Class for serializing program slot information
+ ///
+ public class ProgramInfo
+ {
+ // Shared properties
+
+ [JsonProperty("programNumber")]
+ public uint ProgramNumber { get; private set; }
+
+ [JsonConverter(typeof (StringEnumConverter))]
+ [JsonProperty("operatingState")]
+ public eProgramOperatingState OperatingState { get; set; }
+
+ [JsonConverter(typeof (StringEnumConverter))]
+ [JsonProperty("registrationState")]
+ public eProgramRegistrationState RegistrationState { get; set; }
+
+ [JsonProperty("programFile")]
+ public string ProgramFile { get; set; }
+
+ [JsonProperty("friendlyName")]
+ public string FriendlyName { get; set; }
+
+ [JsonProperty("compilerRevision")]
+ public string CompilerRevision { get; set; }
+
+ [JsonProperty("compileTime")]
+ public string CompileTime { get; set; }
+
+ [JsonProperty("include4Dat")]
+ public string Include4Dat { get; set; }
+
+ // SIMPL Windows properties
+ [JsonProperty("systemName")]
+ public string SystemName { get; set; }
+
+ [JsonProperty("crestronDb")]
+ public string CrestronDb { get; set; }
+
+ [JsonProperty("environment")]
+ public string Environment { get; set; }
+
+ [JsonProperty("programmer")]
+ public string Programmer { get; set; }
+
+
+ // SSP Properties
+ [JsonProperty("applicationName")]
+ public string ApplicationName { get; set; }
+
+ [JsonProperty("programTool")]
+ public string ProgramTool { get; set; }
+
+ [JsonProperty("minFirmwareVersion")]
+ public string MinFirmwareVersion { get; set; }
+
+ [JsonProperty("plugInVersion")]
+ public string PlugInVersion { get; set; }
+
+ public ProgramInfo(uint number)
+ {
+ ProgramNumber = number;
+
+ ProgramFile = "";
+ FriendlyName = "";
+ CompilerRevision = "";
+ CompileTime = "";
+ Include4Dat = "";
+
+ SystemName = "";
+ CrestronDb = "";
+ Environment = "";
+ Programmer = "";
+
+ ApplicationName = "";
+ ProgramTool = "";
+ MinFirmwareVersion = "";
+ PlugInVersion = "";
+ }
+ }
+
+ public class ProgramInfoEventArgs : EventArgs
+ {
+ public ProgramInfo ProgramInfo;
+
+ public ProgramInfoEventArgs(ProgramInfo progInfo)
+ {
+ ProgramInfo = progInfo;
+ }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
index adda54bd..00303250 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
@@ -199,6 +199,7 @@
+
@@ -219,11 +220,14 @@
+
+
+
@@ -282,6 +286,7 @@
+
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec
index 5db86afc..e736dcbf 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec
@@ -14,7 +14,7 @@
crestron 3series 4series
-
+
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs
index f7275a66..01da1c54 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs
@@ -402,13 +402,16 @@ namespace PepperDash.Essentials
/// Loads a
///
///
+ ///
static void LoadCustomPlugin(IPluginDeviceFactory plugin, LoadedAssembly loadedAssembly)
{
var passed = Global.IsRunningMinimumVersionOrHigher(plugin.MinimumEssentialsFrameworkVersion);
if (!passed)
{
- Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", plugin.MinimumEssentialsFrameworkVersion);
+ Debug.Console(0, Debug.ErrorLogLevel.Error,
+ "\r\n********************\r\n\tPlugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin {1}\r\n********************",
+ plugin.MinimumEssentialsFrameworkVersion, loadedAssembly.Name);
return;
}
else
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs
index 4f79626f..d6a9fad0 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs
@@ -1,178 +1,300 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
-
using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-
using PepperDash.Core;
//using SSMono.IO;
+using PepperDash.Core.WebApi.Presets;
namespace PepperDash.Essentials.Core.Presets
{
- ///
- /// Class that represents the model behind presets display
- ///
- public class DevicePresetsModel : Device
- {
- public event EventHandler PresetsLoaded;
+ ///
+ /// Class that represents the model behind presets display
+ ///
+ public class DevicePresetsModel : Device
+ {
+ public delegate void PresetRecalledCallback(ISetTopBoxNumericKeypad device, string channel);
- public int PulseTime { get; set; }
- public int DigitSpacingMS { get; set; }
- public bool PresetsAreLoaded { get; private set; }
+ public delegate void PresetsSavedCallback(List presets);
- public List PresetsList { get { return _PresetsList.ToList(); } }
- List _PresetsList;
- public int Count { get { return PresetsList != null ? PresetsList.Count : 0; } }
+ private readonly CCriticalSection _fileOps = new CCriticalSection();
+ private readonly bool _initSuccess;
- public bool UseLocalImageStorage { get; set; }
- public string ImagesLocalHostPrefix { get; set; }
- public string ImagesPathPrefix { get; set; }
- public string ListPathPrefix { get; set; }
+ private readonly ISetTopBoxNumericKeypad _setTopBox;
- ///
- /// The methods on the STB device to call when dialing
- ///
- Dictionary> DialFunctions;
- Action EnterFunction;
+ ///
+ /// The methods on the STB device to call when dialing
+ ///
+ private Dictionary> _dialFunctions;
- bool DialIsRunning;
- string FilePath;
- bool InitSuccess;
- //SSMono.IO.FileSystemWatcher ListWatcher;
+ private bool _dialIsRunning;
+ private Action _enterFunction;
+ private string _filePath;
- public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
- : base(key)
- {
- PulseTime = 150;
- DigitSpacingMS = 150;
+ public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
+ : this(key, fileName)
+ {
+ try
+ {
+ _setTopBox = setTopBox;
- try
- {
- // Grab the digit functions from the device
- // If any fail, the whole thing fails peacefully
- DialFunctions = new Dictionary>(10)
- {
- { '1', setTopBox.Digit1 },
- { '2', setTopBox.Digit2 },
- { '3', setTopBox.Digit3 },
- { '4', setTopBox.Digit4 },
- { '5', setTopBox.Digit5 },
- { '6', setTopBox.Digit6 },
- { '7', setTopBox.Digit7 },
- { '8', setTopBox.Digit8 },
- { '9', setTopBox.Digit9 },
- { '0', setTopBox.Digit0 },
- { '-', setTopBox.Dash }
- };
- }
- catch
- {
- Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
- DialFunctions = null;
- return;
- }
+ // Grab the digit functions from the device
+ // If any fail, the whole thing fails peacefully
+ _dialFunctions = new Dictionary>(10)
+ {
+ {'1', setTopBox.Digit1},
+ {'2', setTopBox.Digit2},
+ {'3', setTopBox.Digit3},
+ {'4', setTopBox.Digit4},
+ {'5', setTopBox.Digit5},
+ {'6', setTopBox.Digit6},
+ {'7', setTopBox.Digit7},
+ {'8', setTopBox.Digit8},
+ {'9', setTopBox.Digit9},
+ {'0', setTopBox.Digit0},
+ {'-', setTopBox.Dash}
+ };
+ }
+ catch
+ {
+ Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
+ _dialFunctions = null;
+ return;
+ }
- EnterFunction = setTopBox.KeypadEnter;
+ _enterFunction = setTopBox.KeypadEnter;
+ }
- UseLocalImageStorage = true;
+ public DevicePresetsModel(string key, string fileName) : base(key)
+ {
+ PulseTime = 150;
+ DigitSpacingMs = 150;
- ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
- CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS,0);
- ImagesPathPrefix = @"/presets/images.zip/";
- ListPathPrefix = @"/html/presets/lists/";
+ UseLocalImageStorage = true;
- SetFileName(fileName);
+ ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
+ ImagesPathPrefix = @"/presets/images.zip/";
+ ListPathPrefix = @"/html/presets/lists/";
- //ListWatcher = new FileSystemWatcher(@"\HTML\presets\lists");
- //ListWatcher.NotifyFilter = NotifyFilters.LastWrite;
- //ListWatcher.EnableRaisingEvents = true;
- //ListWatcher.Changed += ListWatcher_Changed;
- InitSuccess = true;
- }
+ SetFileName(fileName);
+
+ _initSuccess = true;
+ }
+
+ public event PresetRecalledCallback PresetRecalled;
+ public event PresetsSavedCallback PresetsSaved;
+
+ public int PulseTime { get; set; }
+ public int DigitSpacingMs { get; set; }
+ public bool PresetsAreLoaded { get; private set; }
+
+ public List PresetsList { get; private set; }
+
+ public int Count
+ {
+ get { return PresetsList != null ? PresetsList.Count : 0; }
+ }
+
+ public bool UseLocalImageStorage { get; set; }
+ public string ImagesLocalHostPrefix { get; set; }
+ public string ImagesPathPrefix { get; set; }
+ public string ListPathPrefix { get; set; }
+ public event EventHandler PresetsLoaded;
- public void SetFileName(string path)
- {
- FilePath = ListPathPrefix + path;
- LoadChannels();
- }
+ public void SetFileName(string path)
+ {
+ _filePath = ListPathPrefix + path;
- public void LoadChannels()
- {
- PresetsAreLoaded = false;
- try
- {
- var pl = JsonConvert.DeserializeObject(Crestron.SimplSharp.CrestronIO.File.ReadToEnd(FilePath, Encoding.ASCII));
- Name = pl.Name;
- _PresetsList = pl.Channels;
- }
- catch (Exception e)
- {
- Debug.Console(2, this, "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}", FilePath, e.Message);
- // Just save a default empty list
- _PresetsList = new List();
- }
- PresetsAreLoaded = true;
+ Debug.Console(2, this, "Setting presets file path to {0}", _filePath);
+ LoadChannels();
+ }
- var handler = PresetsLoaded;
- if (handler != null)
- handler(this, EventArgs.Empty);
- }
+ public void LoadChannels()
+ {
+ try
+ {
+ _fileOps.Enter();
- public void Dial(int presetNum)
- {
- if (presetNum <= _PresetsList.Count)
- Dial(_PresetsList[presetNum - 1].Channel);
- }
+ Debug.Console(2, this, "Loading presets from {0}", _filePath);
+ PresetsAreLoaded = false;
+ try
+ {
+ var pl = JsonConvert.DeserializeObject(File.ReadToEnd(_filePath, Encoding.ASCII));
+ Name = pl.Name;
+ PresetsList = pl.Channels;
+ }
+ catch (Exception e)
+ {
+ Debug.Console(2, this,
+ "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}",
+ _filePath, e.Message);
+ // Just save a default empty list
+ PresetsList = new List();
+ }
+ PresetsAreLoaded = true;
- public void Dial(string chanNum)
- {
- if (DialIsRunning || !InitSuccess) return;
- if (DialFunctions == null)
- {
- Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
- return;
- }
+ var handler = PresetsLoaded;
+ if (handler != null)
+ {
+ handler(this, EventArgs.Empty);
+ }
+ }
+ finally
+ {
+ _fileOps.Leave();
+ }
+ }
- DialIsRunning = true;
- CrestronInvoke.BeginInvoke(o =>
- {
- foreach (var c in chanNum.ToCharArray())
- {
- if (DialFunctions.ContainsKey(c))
- Pulse(DialFunctions[c]);
- CrestronEnvironment.Sleep(DigitSpacingMS);
- }
+ public void Dial(int presetNum)
+ {
+ if (presetNum <= PresetsList.Count)
+ {
+ Dial(PresetsList[presetNum - 1].Channel);
+ }
+ }
- if (EnterFunction != null)
- Pulse(EnterFunction);
- DialIsRunning = false;
- });
- }
+ public void Dial(string chanNum)
+ {
+ if (_dialIsRunning || !_initSuccess)
+ {
+ return;
+ }
+ if (_dialFunctions == null)
+ {
+ Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
+ return;
+ }
- void Pulse(Action act)
- {
- act(true);
- CrestronEnvironment.Sleep(PulseTime);
- act(false);
- }
+ _dialIsRunning = true;
+ CrestronInvoke.BeginInvoke(o =>
+ {
+ foreach (var c in chanNum.ToCharArray())
+ {
+ if (_dialFunctions.ContainsKey(c))
+ {
+ Pulse(_dialFunctions[c]);
+ }
+ CrestronEnvironment.Sleep(DigitSpacingMs);
+ }
- ///
- /// Event handler for filesystem watcher. When directory changes, this is called
- ///
- //void ListWatcher_Changed(object sender, FileSystemEventArgs e)
- //{
- // Debug.Console(1, this, "folder modified: {0}", e.FullPath);
- // if (e.FullPath.Equals(FilePath, StringComparison.OrdinalIgnoreCase))
- // {
- // Debug.Console(1, this, "File changed: {0}", e.ChangeType);
- // LoadChannels();
- // }
- //}
- }
+ if (_enterFunction != null)
+ {
+ Pulse(_enterFunction);
+ }
+ _dialIsRunning = false;
+ });
+
+ if (_setTopBox == null) return;
+
+ OnPresetRecalled(_setTopBox, chanNum);
+ }
+
+ public void Dial(int presetNum, ISetTopBoxNumericKeypad setTopBox)
+ {
+ if (presetNum <= PresetsList.Count)
+ {
+ Dial(PresetsList[presetNum - 1].Channel, setTopBox);
+ }
+ }
+
+ public void Dial(string chanNum, ISetTopBoxNumericKeypad setTopBox)
+ {
+ _dialFunctions = new Dictionary>(10)
+ {
+ {'1', setTopBox.Digit1},
+ {'2', setTopBox.Digit2},
+ {'3', setTopBox.Digit3},
+ {'4', setTopBox.Digit4},
+ {'5', setTopBox.Digit5},
+ {'6', setTopBox.Digit6},
+ {'7', setTopBox.Digit7},
+ {'8', setTopBox.Digit8},
+ {'9', setTopBox.Digit9},
+ {'0', setTopBox.Digit0},
+ {'-', setTopBox.Dash}
+ };
+
+ _enterFunction = setTopBox.KeypadEnter;
+
+ OnPresetRecalled(setTopBox, chanNum);
+
+ Dial(chanNum);
+ }
+
+ private void OnPresetRecalled(ISetTopBoxNumericKeypad setTopBox, string channel)
+ {
+ var handler = PresetRecalled;
+
+ if (handler == null)
+ {
+ return;
+ }
+
+ handler(setTopBox, channel);
+ }
+
+ public void UpdatePreset(int index, PresetChannel preset)
+ {
+ if (index >= PresetsList.Count)
+ {
+ return;
+ }
+
+ PresetsList[index] = preset;
+
+ SavePresets();
+
+ OnPresetsSaved();
+ }
+
+ public void UpdatePresets(List presets)
+ {
+ PresetsList = presets;
+
+ SavePresets();
+
+ OnPresetsSaved();
+ }
+
+ private void SavePresets()
+ {
+ try
+ {
+ _fileOps.Enter();
+ var pl = new PresetsList {Channels = PresetsList, Name = Name};
+ var json = JsonConvert.SerializeObject(pl, Formatting.Indented);
+
+ using (var file = File.Open(_filePath, FileMode.Truncate))
+ {
+ file.Write(json, Encoding.UTF8);
+ }
+ }
+ finally
+ {
+ _fileOps.Leave();
+ }
+
+ }
+
+ private void OnPresetsSaved()
+ {
+ var handler = PresetsSaved;
+
+ if (handler == null) return;
+
+ handler(PresetsList);
+ }
+
+ private void Pulse(Action act)
+ {
+ act(true);
+ CrestronEnvironment.Sleep(PulseTime);
+ act(false);
+ }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetChannel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetChannel.cs
index b9650e60..259ccbb9 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetChannel.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetChannel.cs
@@ -10,19 +10,22 @@ namespace PepperDash.Essentials.Core.Presets
public class PresetChannel
{
- [JsonProperty(Required = Required.Always)]
+ [JsonProperty(Required = Required.Always,PropertyName = "name")]
public string Name { get; set; }
- [JsonProperty(Required = Required.Always)]
+
+ [JsonProperty(Required = Required.Always, PropertyName = "iconUrl")]
public string IconUrl { get; set; }
- [JsonProperty(Required = Required.Always)]
+
+ [JsonProperty(Required = Required.Always, PropertyName = "channel")]
public string Channel { get; set; }
}
public class PresetsList
{
- [JsonProperty(Required=Required.Always)]
+ [JsonProperty(Required=Required.Always,PropertyName = "name")]
public string Name { get; set; }
- [JsonProperty(Required = Required.Always)]
+
+ [JsonProperty(Required = Required.Always, PropertyName = "channels")]
public List Channels { get; set; }
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs
index 92c97248..fce6291d 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs
@@ -40,7 +40,7 @@ namespace PepperDash_Essentials_Core.Queues
private void Validate(IBasicCommunication coms, object message)
{
- if (_coms == null)
+ if (coms == null)
throw new ArgumentNullException("coms");
if (message == null)
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs
index 1f27fe1e..b4c6befa 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs
@@ -15,23 +15,37 @@ namespace PepperDash_Essentials_Core.Queues
protected readonly Thread _worker;
protected readonly CEvent _waitHandle = new CEvent();
- private readonly bool _delayEnabled;
- private readonly int _delayTime;
+ private bool _delayEnabled;
+ private int _delayTime;
///
/// If the instance has been disposed.
///
public bool Disposed { get; private set; }
+ ///
+ /// Constructor with no thread priority
+ ///
+ ///
+ public GenericQueue(string key)
+ : this(key, Thread.eThreadPriority.MediumPriority)
+ {
+
+ }
+
///
/// Constructor for generic queue with no pacing
///
/// Key
- public GenericQueue(string key)
+ ///
+ public GenericQueue(string key, Thread.eThreadPriority priority)
{
_key = key;
- _queue = new CrestronQueue();
- _worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running);
+ _queue = new CrestronQueue(25);
+ _worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running)
+ {
+ Priority = priority
+ };
CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
{
@@ -49,11 +63,28 @@ namespace PepperDash_Essentials_Core.Queues
/// Pacing in ms between actions
public GenericQueue(string key, int pacing)
: this(key)
+ {
+ SetDelayValues(pacing);
+ }
+
+ ///
+ /// Constructor with pacing and priority
+ ///
+ ///
+ ///
+ ///
+ public GenericQueue(string key, int pacing, Thread.eThreadPriority priority)
+ : this(key, priority)
+ {
+ SetDelayValues(pacing);
+ }
+
+ private void SetDelayValues(int pacing)
{
_delayEnabled = pacing > 0;
_delayTime = pacing;
}
-
+
///
/// Thread callback
///
@@ -83,7 +114,7 @@ namespace PepperDash_Essentials_Core.Queues
}
catch (Exception ex)
{
- Debug.ConsoleWithLog(0, this, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
+ Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
}
}
else _waitHandle.Wait();
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs
new file mode 100644
index 00000000..cd0c2586
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs
@@ -0,0 +1,41 @@
+using System.Collections.Generic;
+using Crestron.SimplSharp.Scheduler;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.Room.Config
+{
+ public class EssentialsRoomScheduledEventsConfig
+ {
+ [JsonProperty("scheduledEvents")]
+ public List ScheduledEvents;
+ }
+
+ public class ScheduledEventConfig
+ {
+ [JsonProperty("key")]
+ public string Key;
+
+ [JsonProperty("name")]
+ public string Name;
+
+ [JsonProperty("days")]
+ public ScheduledEventCommon.eWeekDays Days;
+
+ [JsonProperty("time")]
+ public string Time;
+
+ [JsonProperty("actions")]
+ public List Actions;
+
+ [JsonProperty("persistent")]
+ public bool Persistent;
+
+ [JsonProperty("acknowledgeable")]
+ public bool Acknowledgeable;
+
+ [JsonProperty("enable")]
+ public bool Enable;
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs
index 1743bdaa..82871228 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs
@@ -41,6 +41,14 @@ namespace PepperDash.Essentials.Core
}
+ ///
+ /// Simplified routing direct from source to destination
+ ///
+ public interface IRunDirectRouteAction
+ {
+ void RunDirectRoute(string sourceKey, string destinationKey);
+ }
+
///
/// For rooms that default presentation only routing
///
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs
index 09c7988a..3c5567c4 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs
@@ -49,7 +49,9 @@ namespace PepperDash.Essentials.DM
public BoolFeedback EnableAudioBreakawayFeedback { get; private set; }
public BoolFeedback EnableUsbBreakawayFeedback { get; private set; }
- public Dictionary InputCardHdcpStateFeedbacks { get; private set; }
+ public Dictionary InputCardHdcpStateFeedbacks { get; private set; }
+ public Dictionary InputStreamCardStateFeedbacks { get; private set; }
+ public Dictionary OutputStreamCardStateFeedbacks { get; private set; }
public Dictionary InputCardHdcpCapabilityTypes { get; private set; }
@@ -223,7 +225,9 @@ namespace PepperDash.Essentials.DM
EnableUsbBreakawayFeedback =
new BoolFeedback(() => (Chassis as DmMDMnxn).EnableUSBBreakawayFeedback.BoolValue);
- InputCardHdcpStateFeedbacks = new Dictionary();
+ InputCardHdcpStateFeedbacks = new Dictionary();
+ InputStreamCardStateFeedbacks = new Dictionary();
+ OutputStreamCardStateFeedbacks = new Dictionary();
InputCardHdcpCapabilityTypes = new Dictionary();
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++)
@@ -307,6 +311,33 @@ namespace PepperDash.Essentials.DM
// return hdMdNxMHdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue;
return false;
+ });
+ OutputStreamCardStateFeedbacks[tempX] = new IntFeedback(() =>
+ {
+ try
+ {
+ var outputCard = Chassis.Outputs[tempX];
+
+ if (outputCard.Card is DmcStroAV)
+ {
+ Debug.Console(2, "Found output stream card in slot: {0}.", tempX);
+ var streamCard = outputCard.Card as DmcStroAV;
+ if (streamCard.Control.StartFeedback.BoolValue == true)
+ return 1;
+ else if (streamCard.Control.StopFeedback.BoolValue == true)
+ return 2;
+ else if (streamCard.Control.PauseFeedback.BoolValue == true)
+ return 3;
+ else
+ return 0;
+ }
+ return 0;
+ }
+ catch (InvalidOperationException iopex)
+ {
+ Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "Error adding output stream card in slot: {0}. Error: {1}", tempX, iopex);
+ return 0;
+ }
});
}
@@ -406,6 +437,33 @@ namespace PepperDash.Essentials.DM
Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "The Input Card in slot: {0} supports HDCP 2. Please update the configuration value in the inputCardSupportsHdcp2 object to true. Error: {1}", tempX, iopex);
return 0;
}
+ });
+ InputStreamCardStateFeedbacks[tempX] = new IntFeedback(() =>
+ {
+ try
+ {
+ var inputCard = Chassis.Inputs[tempX];
+
+ if (inputCard.Card is DmcStr)
+ {
+ Debug.Console(2, "Found input stream card in slot: {0}.", tempX);
+ var streamCard = inputCard.Card as DmcStr;
+ if (streamCard.Control.StartFeedback.BoolValue == true)
+ return 1;
+ else if (streamCard.Control.StopFeedback.BoolValue == true)
+ return 2;
+ else if (streamCard.Control.PauseFeedback.BoolValue == true)
+ return 3;
+ else
+ return 0;
+ }
+ return 0;
+ }
+ catch (InvalidOperationException iopex)
+ {
+ Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "Error adding input stream card in slot: {0}. Error: {1}", tempX, iopex);
+ return 0;
+ }
});
}
}
@@ -915,6 +973,19 @@ namespace PepperDash.Essentials.DM
else
Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks");
break;
+ }
+ case DMInputEventIds.StartEventId:
+ case DMInputEventIds.StopEventId:
+ case DMInputEventIds.PauseEventId:
+ {
+ Debug.Console(2, this, "DM Input {0} Stream Status EventId", args.Number);
+ if (InputStreamCardStateFeedbacks[args.Number] != null)
+ {
+ InputStreamCardStateFeedbacks[args.Number].FireUpdate();
+ }
+ else
+ Debug.Console(2, this, "No index of {0} found in InputStreamCardStateFeedbacks");
+ break;
}
default:
{
@@ -1043,6 +1114,19 @@ namespace PepperDash.Essentials.DM
Debug.Console(2, this, "DM Output {0} DisabledByHdcpEventId", args.Number);
OutputDisabledByHdcpFeedbacks[args.Number].FireUpdate();
break;
+ }
+ case DMOutputEventIds.StartEventId:
+ case DMOutputEventIds.StopEventId:
+ case DMOutputEventIds.PauseEventId:
+ {
+ Debug.Console(2, this, "DM Output {0} Stream Status EventId", args.Number);
+ if (OutputStreamCardStateFeedbacks[args.Number] != null)
+ {
+ OutputStreamCardStateFeedbacks[args.Number].FireUpdate();
+ }
+ else
+ Debug.Console(2, this, "No index of {0} found in OutputStreamCardStateFeedbacks");
+ break;
}
default:
{
@@ -1242,13 +1326,16 @@ namespace PepperDash.Essentials.DM
}
else
{
- LinkHdmiInputToApi(trilist, ioSlot, joinMap, ioSlotJoin);
- }
-
- if (RxDictionary.ContainsKey(ioSlot))
- {
- LinkRxToApi(trilist, ioSlot, joinMap, ioSlotJoin);
- }
+ LinkHdmiInputToApi(trilist, ioSlot, joinMap, ioSlotJoin);
+ LinkStreamInputToApi(trilist, ioSlot, joinMap, ioSlotJoin);
+ }
+
+ if (RxDictionary.ContainsKey(ioSlot))
+ {
+ LinkRxToApi(trilist, ioSlot, joinMap, ioSlotJoin);
+ }
+ else
+ LinkStreamOutputToApi(trilist, ioSlot, joinMap, ioSlotJoin);
}
}
@@ -1295,6 +1382,86 @@ namespace PepperDash.Essentials.DM
{
trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1;
}
+ }
+
+ private void LinkStreamInputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin)
+ {
+ var inputPort = InputPorts[string.Format("inputCard{0}--streamIn", ioSlot)];
+ if (inputPort == null)
+ {
+ return;
+ }
+ var streamCard = Chassis.Inputs[ioSlot].Card as DmcStr;
+ var join = joinMap.InputStreamCardState.JoinNumber + ioSlotJoin;
+
+ Debug.Console(1, "Port value for input card {0} is set as a stream card", ioSlot);
+
+ trilist.SetUShortSigAction(join, s =>
+ {
+ if (s == 1)
+ {
+ Debug.Console(2, this, "Join {0} value {1}: Setting stream state to start", join, s);
+ streamCard.Control.Start();
+ }
+ else if (s == 2)
+ {
+ Debug.Console(2, this, "Join {0} value {1}: Setting stream state to stop", join, s);
+ streamCard.Control.Stop();
+ }
+ else if (s == 3)
+ {
+ Debug.Console(2, this, "Join {0} value {1}: Setting stream state to pause", join, s);
+ streamCard.Control.Pause();
+ }
+ else
+ {
+ Debug.Console(2, this, "Join {0} value {1}: Ignore stream state", join, s);
+ }
+ });
+
+ InputStreamCardStateFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[join]);
+
+ trilist.UShortInput[join].UShortValue = InputStreamCardStateFeedbacks[ioSlot].UShortValue;
+ }
+
+ private void LinkStreamOutputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin)
+ {
+ var outputPort = OutputPorts[string.Format("outputCard{0}--streamOut", ioSlot)];
+ if (outputPort == null)
+ {
+ return;
+ }
+ var streamCard = Chassis.Outputs[ioSlot].Card as DmcStroAV;
+ var join = joinMap.OutputStreamCardState.JoinNumber + ioSlotJoin;
+
+ Debug.Console(1, "Port value for output card {0} is set as a stream card", ioSlot);
+
+ trilist.SetUShortSigAction(join, s =>
+ {
+ if (s == 1)
+ {
+ Debug.Console(2, this, "Join {0} value {1}: Setting stream state to start", join, s);
+ streamCard.Control.Start();
+ }
+ else if (s == 2)
+ {
+ Debug.Console(2, this, "Join {0} value {1}: Setting stream state to stop", join, s);
+ streamCard.Control.Stop();
+ }
+ else if (s == 3)
+ {
+ Debug.Console(2, this, "Join {0} value {1}: Setting stream state to pause", join, s);
+ streamCard.Control.Pause();
+ }
+ else
+ {
+ Debug.Console(2, this, "Join {0} value {1}: Ignore stream state", join, s);
+ }
+ });
+
+ OutputStreamCardStateFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[join]);
+
+ trilist.UShortInput[join].UShortValue = OutputStreamCardStateFeedbacks[ioSlot].UShortValue;
}
private void LinkRxToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin)
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs
index d7996554..39e549cc 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs
@@ -39,12 +39,12 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
{
_dge = device;
_dgeEthernetInfo = _dge.ExtenderEthernetReservedSigs;
- _dgeEthernetInfo.DeviceExtenderSigChange += (extender, args) => UpdateDeviceInfo();
+ //_dgeEthernetInfo.DeviceExtenderSigChange += (extender, args) => UpdateDeviceInfo();
_dgeEthernetInfo.Use();
DeviceInfo = new DeviceInfo();
- _dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); };
+ //_dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); };
_dc = dc;
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs
index 1e44396c..fb8f3ac5 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs
@@ -1,44 +1,44 @@
-using Crestron.SimplSharpPro;
-using System;
-using System.Linq;
-//using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.DM;
-using Crestron.SimplSharpPro.DM.Endpoints;
-using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
-
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-
-namespace PepperDash.Essentials.DM
-{
- using eVst = eX02VideoSourceType;
- using eAst = eX02AudioSourceType;
-
-
+using Crestron.SimplSharpPro;
+using System;
+using System.Linq;
+//using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DM;
+using Crestron.SimplSharpPro.DM.Endpoints;
+using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+
+namespace PepperDash.Essentials.DM
+{
+ using eVst = eX02VideoSourceType;
+ using eAst = eX02AudioSourceType;
+
+
[Description("Wrapper class for DM-TX-4K-Z-302-C")]
- public class DmTx4kz302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback,
- IIROutputPorts, IComPorts
- {
- public DmTx4kz302C Tx { get; private set; }
-
- public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
- public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
- public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; }
- public RoutingOutputPort DmOut { get; private set; }
- public RoutingOutputPort HdmiLoopOut { get; private set; }
-
- public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
- public IntFeedback VideoSourceNumericFeedback { get; protected set; }
- public IntFeedback AudioSourceNumericFeedback { get; protected set; }
- public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
- public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
- public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
- public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
- public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; }
-
- //public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
+ public class DmTx4kz302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback,
+ IIROutputPorts, IComPorts
+ {
+ public DmTx4kz302C Tx { get; private set; }
+
+ public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
+ public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
+ public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; }
+ public RoutingOutputPort DmOut { get; private set; }
+ public RoutingOutputPort HdmiLoopOut { get; private set; }
+
+ public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
+ public IntFeedback VideoSourceNumericFeedback { get; protected set; }
+ public IntFeedback AudioSourceNumericFeedback { get; protected set; }
+ public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
+ public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
+ public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
+ public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
+ public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; }
+
+ //public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
//public override ushort HdcpSupportCapability { get; protected set; }
//IroutingNumericEvent
@@ -52,272 +52,286 @@ namespace PepperDash.Essentials.DM
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
- }
-
- ///
- /// Helps get the "real" inputs, including when in Auto
- ///
- public eX02VideoSourceType ActualActiveVideoInput
- {
- get
- {
- if (Tx.VideoSourceFeedback != eVst.Auto)
- return Tx.VideoSourceFeedback;
- if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
- return eVst.Hdmi1;
- if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
- return eVst.Hdmi2;
-
- return Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue ? eVst.Vga : eVst.AllDisabled;
- }
- }
- public RoutingPortCollection InputPorts
- {
- get
- {
- return new RoutingPortCollection
- {
- HdmiIn1,
- HdmiIn2,
- DisplayPortIn,
- AnyVideoInput
- };
- }
- }
- public RoutingPortCollection OutputPorts
- {
- get
- {
- return new RoutingPortCollection { DmOut, HdmiLoopOut };
- }
- }
- public DmTx4kz302CController(string key, string name, DmTx4kz302C tx)
- : base(key, name, tx)
- {
- Tx = tx;
-
- HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
- eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
+ }
+
+ ///
+ /// Helps get the "real" inputs, including when in Auto
+ ///
+ public eX02VideoSourceType ActualActiveVideoInput
+ {
+ get
+ {
+ if (Tx.VideoSourceFeedback != eVst.Auto)
+ return Tx.VideoSourceFeedback;
+ if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
+ return eVst.Hdmi1;
+ if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
+ return eVst.Hdmi2;
+
+ return Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue ? eVst.Vga : eVst.AllDisabled;
+ }
+ }
+ public RoutingPortCollection InputPorts
+ {
+ get
+ {
+ return new RoutingPortCollection
+ {
+ HdmiIn1,
+ HdmiIn2,
+ DisplayPortIn,
+ AnyVideoInput
+ };
+ }
+ }
+ public RoutingPortCollection OutputPorts
+ {
+ get
+ {
+ return new RoutingPortCollection { DmOut, HdmiLoopOut };
+ }
+ }
+ public DmTx4kz302CController(string key, string name, DmTx4kz302C tx)
+ : base(key, name, tx)
+ {
+ Tx = tx;
+
+ HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
+ eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1]))
{
FeedbackMatchObject = eVst.Hdmi1
- };
- HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
- eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
+ };
+ HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
+ eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2]))
{
FeedbackMatchObject = eVst.Hdmi2
- };
- DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn,
- eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DisplayPort, eVst.DisplayPort, this,
+ };
+ DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn,
+ eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DisplayPort, eVst.DisplayPort, this,
VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput))
{
FeedbackMatchObject = eVst.DisplayPort
- };
- ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
- () => ActualActiveVideoInput.ToString());
-
- Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
- Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
- Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange;
- Tx.BaseEvent += Tx_BaseEvent;
- Tx.OnlineStatusChange += Tx_OnlineStatusChange;
-
- VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
- AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
-
- HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
-
- HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
-
- HdcpStateFeedback =
- new IntFeedback(
- () =>
- tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback
- ? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback
- : (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
-
- HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
-
- Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
-
- Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
-
- DisplayPortVideoSyncFeedback = new BoolFeedback(() => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue);
-
-
- var combinedFuncs = new VideoStatusFuncsWrapper
- {
- HdcpActiveFeedbackFunc = () =>
- (ActualActiveVideoInput == eVst.Hdmi1
- && tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
- || (ActualActiveVideoInput == eVst.Hdmi2
- && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
-
- HdcpStateFeedbackFunc = () =>
- {
- if (ActualActiveVideoInput == eVst.Hdmi1)
- return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
- return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : "";
- },
-
- VideoResolutionFeedbackFunc = () =>
- {
- if (ActualActiveVideoInput == eVst.Hdmi1)
- return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
- if (ActualActiveVideoInput == eVst.Hdmi2)
- return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
- return ActualActiveVideoInput == eVst.Vga ? tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString() : "";
- },
- VideoSyncFeedbackFunc = () =>
- (ActualActiveVideoInput == eVst.Hdmi1
- && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
- || (ActualActiveVideoInput == eVst.Hdmi2
- && tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
- || (ActualActiveVideoInput == eVst.Vga
- && tx.DisplayPortInput.SyncDetectedFeedback.BoolValue)
-
- };
-
- AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
- eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
-
- DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
- eRoutingPortConnectionType.DmCat, null, this);
- HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
- eRoutingPortConnectionType.Hdmi, null, this);
-
-
- AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
- AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
- AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
- AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
- Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, DisplayPortVideoSyncFeedback);
-
- // Set Ports for CEC
- HdmiIn1.Port = Tx.HdmiInputs[1];
- HdmiIn2.Port = Tx.HdmiInputs[2];
- HdmiLoopOut.Port = Tx.HdmiOutput;
- DmOut.Port = Tx.DmOutput;
- }
-
- void DisplayPortInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
- {
- Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
-
- switch (args.EventId)
- {
- case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
- DisplayPortVideoSyncFeedback.FireUpdate();
- break;
- }
- }
-
-
-
- public override bool CustomActivate()
- {
- // Link up all of these damned events to the various RoutingPorts via a helper handler
- Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
- Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
-
- Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
- Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
-
- Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId);
- Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, a.EventId);
-
- // Base does register and sets up comm monitoring.
- return base.CustomActivate();
- }
-
- public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
- {
- var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
-
- if (Hdmi1VideoSyncFeedback != null)
- {
- Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
- }
- if (Hdmi2VideoSyncFeedback != null)
- {
- Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
- }
- if (DisplayPortVideoSyncFeedback != null)
- {
- DisplayPortVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input3VideoSyncStatus.JoinNumber]);
- }
-
- LinkDmTxToApi(this, trilist, joinMap, bridge);
- }
-
- public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
- {
- Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
-
- switch (input)
- {
- case 0:
- {
- ExecuteSwitch(eVst.Auto, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
- break;
- }
- case 1:
- {
- ExecuteSwitch(HdmiIn1.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
- break;
- }
- case 2:
- {
- ExecuteSwitch(HdmiIn2.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
- break;
- }
- case 3:
- {
- ExecuteSwitch(DisplayPortIn.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
- break;
- }
- case 4:
- {
- ExecuteSwitch(eVst.AllDisabled, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
- break;
- }
- }
-
-
- }
-
- public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
- {
- if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
- Tx.VideoSource = (eVst)inputSelector;
-
- // NOTE: It's possible that this particular TX model may not like the AudioSource property being set.
- // The SIMPL definition only shows a single analog for AudioVideo Source
- if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
- //it doesn't
- Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key);
- //Tx.AudioSource = (eAst)inputSelector;
- }
-
- void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
- {
- Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
-
- switch (args.EventId)
- {
- case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
- case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
- case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
- if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
- if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
- HdcpStateFeedback.FireUpdate();
- break;
- case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
- if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
- if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
- break;
- }
+ };
+ ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
+ () => ActualActiveVideoInput.ToString());
+
+ Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
+ Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
+ Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange;
+ Tx.BaseEvent += Tx_BaseEvent;
+ Tx.OnlineStatusChange += Tx_OnlineStatusChange;
+
+ VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
+ AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
+
+ HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
+
+ HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
+
+ HdcpStateFeedback =
+ new IntFeedback(
+ () =>
+ tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback
+ ? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback
+ : (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
+
+ HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
+
+ Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
+
+ Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
+
+ DisplayPortVideoSyncFeedback = new BoolFeedback(() => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue);
+
+
+ var combinedFuncs = new VideoStatusFuncsWrapper
+ {
+ HdcpActiveFeedbackFunc = () =>
+ (ActualActiveVideoInput == eVst.Hdmi1
+ && tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
+ || (ActualActiveVideoInput == eVst.Hdmi2
+ && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
+
+ HdcpStateFeedbackFunc = () =>
+ {
+ if (ActualActiveVideoInput == eVst.Hdmi1)
+ return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
+ return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : "";
+ },
+
+ VideoResolutionFeedbackFunc = () =>
+ {
+ if (ActualActiveVideoInput == eVst.Hdmi1)
+ return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
+ if (ActualActiveVideoInput == eVst.Hdmi2)
+ return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
+ return ActualActiveVideoInput == eVst.Vga ? tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString() : "";
+ },
+ VideoSyncFeedbackFunc = () =>
+ (ActualActiveVideoInput == eVst.Hdmi1
+ && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
+ || (ActualActiveVideoInput == eVst.Hdmi2
+ && tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
+ || (ActualActiveVideoInput == eVst.Vga
+ && tx.DisplayPortInput.SyncDetectedFeedback.BoolValue)
+
+ };
+
+ AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
+ eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
+
+ DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
+ eRoutingPortConnectionType.DmCat, null, this);
+ HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
+ eRoutingPortConnectionType.Hdmi, null, this);
+
+
+ AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
+ AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
+ AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
+ AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
+ Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, DisplayPortVideoSyncFeedback);
+
+ // Set Ports for CEC
+ HdmiIn1.Port = Tx.HdmiInputs[1];
+ HdmiIn2.Port = Tx.HdmiInputs[2];
+ HdmiLoopOut.Port = Tx.HdmiOutput;
+ DmOut.Port = Tx.DmOutput;
+ }
+
+ void DisplayPortInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
+ {
+ Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
+
+ switch (args.EventId)
+ {
+ case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
+ DisplayPortVideoSyncFeedback.FireUpdate();
+ break;
+ }
+ }
+
+
+
+ public override bool CustomActivate()
+ {
+ // Link up all of these damned events to the various RoutingPorts via a helper handler
+ Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
+ Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
+
+ Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
+ Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
+
+ Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId);
+ Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, a.EventId);
+
+ // Base does register and sets up comm monitoring.
+ return base.CustomActivate();
+ }
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
+
+ if (Hdmi1VideoSyncFeedback != null)
+ {
+ Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
+ }
+ if (Hdmi2VideoSyncFeedback != null)
+ {
+ Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
+ }
+ if (DisplayPortVideoSyncFeedback != null)
+ {
+ DisplayPortVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input3VideoSyncStatus.JoinNumber]);
+ }
+
+ LinkDmTxToApi(this, trilist, joinMap, bridge);
+ }
+
+ public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
+ {
+ Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
+
+ switch (input)
+ {
+ case 0:
+ {
+ ExecuteSwitch(eVst.Auto, null, type);
+ break;
+ }
+ case 1:
+ {
+ ExecuteSwitch(HdmiIn1.Selector, null, type);
+ break;
+ }
+ case 2:
+ {
+ ExecuteSwitch(HdmiIn2.Selector, null, type);
+ break;
+ }
+ case 3:
+ {
+ ExecuteSwitch(DisplayPortIn.Selector, null, type);
+ break;
+ }
+ case 4:
+ {
+ ExecuteSwitch(eVst.AllDisabled, null, type);
+ break;
+ }
+ default:
+ {
+ Debug.Console(2, this, "Unable to execute numeric switch to input {0}", input);
+ break;
+ }
+
+ }
+
+
+ }
+
+ public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
+ {
+ try
+ {
+ Debug.Console(2, this, "Attempting to switch InputSelector {0}", ((eVst)inputSelector).ToString());
+ if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
+ Tx.VideoSource = (eVst)inputSelector;
+
+ // NOTE: It's possible that this particular TX model may not like the AudioSource property being set.
+ // The SIMPL definition only shows a single analog for AudioVideo Source
+ if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
+ //it doesn't
+ Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key);
+ //Tx.AudioSource = (eAst)inputSelector;
+ }
+ catch (Exception e)
+ {
+ Debug.Console(2, this, "Exception in ExecuteSwitch: {0}", e);
+ }
+ }
+
+ void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
+ {
+ Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
+
+ switch (args.EventId)
+ {
+ case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
+ case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
+ case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
+ if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
+ if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
+ HdcpStateFeedback.FireUpdate();
+ break;
+ case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
+ if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
+ if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
+ break;
+ }
}
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
@@ -356,57 +370,57 @@ namespace PepperDash.Essentials.DM
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break;
}
- }
-
- ///
- /// Relays the input stream change to the appropriate RoutingInputPort.
- ///
- void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
- {
- if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) return;
- inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
- }
-
- ///
- /// Relays the VideoAttributes change to a RoutingInputPort
- ///
- void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
- {
- //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
- //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
- // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
- switch (eventId)
- {
- case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
- inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.HdcpStateFeedbackEventId:
- inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
- case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
- inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
- inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
- break;
- }
- }
-
-
- #region IIROutputPorts Members
- public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } }
- public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
- #endregion
-
- #region IComPorts Members
- public CrestronCollection ComPorts { get { return Tx.ComPorts; } }
- public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
- #endregion
- }
+ }
+
+ ///
+ /// Relays the input stream change to the appropriate RoutingInputPort.
+ ///
+ void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
+ {
+ if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) return;
+ inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
+ }
+
+ ///
+ /// Relays the VideoAttributes change to a RoutingInputPort
+ ///
+ void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
+ {
+ //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
+ //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
+ // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
+ switch (eventId)
+ {
+ case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
+ inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.HdcpStateFeedbackEventId:
+ inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
+ case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
+ inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
+ inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ break;
+ }
+ }
+
+
+ #region IIROutputPorts Members
+ public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } }
+ public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
+ #endregion
+
+ #region IComPorts Members
+ public CrestronCollection ComPorts { get { return Tx.ComPorts; } }
+ public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs
index fd80ac1f..4d8e41f6 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs
@@ -122,7 +122,9 @@ namespace PepperDash.Essentials.DM
return new DmTx4kz302CController(key, name, new DmTx4kz302C(chassis.Inputs[num]));
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(chassis.Inputs[num]));
- }
+ if (typeName.StartsWith("hdbasettx"))
+ return new HDBaseTTxController(key, name, new HDTx3CB(chassis.Inputs[num]));
+ }
else
{
if (typeName.StartsWith("dmtx200"))
@@ -145,7 +147,9 @@ namespace PepperDash.Essentials.DM
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(ipid, chassis.Inputs[num]));
- }
+ if (typeName.StartsWith("hdbasettx"))
+ return new HDBaseTTxController(key, name, new HDTx3CB(ipid, chassis.Inputs[num]));
+ }
}
catch (Exception e)
{
@@ -355,7 +359,7 @@ namespace PepperDash.Essentials.DM
public DmTxControllerFactory()
{
TypeNames = new List() { "dmtx200c", "dmtx201c", "dmtx201s", "dmtx4k100c", "dmtx4k202c", "dmtx4kz202c", "dmtx4k302c", "dmtx4kz302c",
- "dmtx401c", "dmtx401s", "dmtx4k100c1g", "dmtx4kz100c1g" };
+ "dmtx401c", "dmtx401s", "dmtx4k100c1g", "dmtx4kz100c1g", "hdbasettx" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs
new file mode 100644
index 00000000..800da2a9
--- /dev/null
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
+using Newtonsoft.Json;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+
+namespace PepperDash.Essentials.DM
+{
+ ///
+ /// Controller class for suitable for HDBaseT transmitters
+ ///
+ [Description("Wrapper Class for HDBaseT devices based on HDTx3CB class")]
+ public class HDBaseTTxController: BasicDmTxControllerBase, IRoutingInputsOutputs, IComPorts
+ {
+ public RoutingInputPort HdmiIn { get; private set; }
+ public RoutingOutputPort DmOut { get; private set; }
+
+ public HDBaseTTxController(string key, string name, HDTx3CB tx)
+ : base(key, name, tx)
+ {
+ HdmiIn = new RoutingInputPort(DmPortName.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
+ eRoutingPortConnectionType.Hdmi, null, this) { Port = tx };
+
+ DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
+ eRoutingPortConnectionType.DmCat, null, this);
+
+ InputPorts = new RoutingPortCollection { HdmiIn };
+ OutputPorts = new RoutingPortCollection { DmOut };
+ }
+
+ #region IRoutingInputs Members
+
+ public RoutingPortCollection InputPorts { get; private set; }
+
+ #endregion
+
+ #region IRoutingOutputs Members
+
+ public RoutingPortCollection OutputPorts { get; private set; }
+
+ #endregion
+
+ #region IComPorts Members
+
+ public CrestronCollection ComPorts { get { return (Hardware as HDTx3CB).ComPorts; } }
+ public int NumberOfComPorts { get { return (Hardware as HDTx3CB).NumberOfComPorts; } }
+
+ #endregion
+
+ #region CrestronBridgeableBaseDevice abstract overrides
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = new HDBaseTTxControllerJoinMap(joinStart);
+
+ var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
+
+ if (!string.IsNullOrEmpty(joinMapSerialized))
+ joinMap = JsonConvert.DeserializeObject(joinMapSerialized);
+
+
+ if (bridge != null)
+ {
+ bridge.AddJoinMap(Key, joinMap);
+ }
+ else
+ {
+ Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
+ }
+
+ Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+
+ this.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
+
+ }
+
+ #endregion
+ }
+
+ public class HDBaseTTxControllerJoinMap : JoinMapBaseAdvanced
+ {
+ [JoinName("IsOnline")]
+ public JoinDataComplete IsOnline = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 1,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "HDBaseT device online feedback",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ ///
+ /// Plugin device BridgeJoinMap constructor
+ ///
+ /// This will be the join it starts on the EISC bridge
+ public HDBaseTTxControllerJoinMap(uint joinStart)
+ : base(joinStart, typeof(HDBaseTTxControllerJoinMap))
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj
index 69045ea5..63b20c98 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj
+++ b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj
@@ -65,12 +65,12 @@
False
- ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll
+ ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll
False
False
- ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll
+ ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll
False
@@ -79,7 +79,7 @@
False
- ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe
+ ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe
False
@@ -108,6 +108,7 @@
+
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj
index 54d37613..bfee822e 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj
@@ -69,12 +69,12 @@
False
- ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll
+ ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll
False
False
- ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll
+ ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll
False
@@ -83,7 +83,7 @@
False
- ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe
+ ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe
False
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs
index 97aacb2d..2746a04a 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs
@@ -54,7 +54,7 @@ namespace PepperDash.Essentials.Devices.Common
KeypadAccessoryButton1Label = "-";
HasKeypadAccessoryButton2 = true;
- KeypadAccessoryButton2Command = "NumericEnter";
+ KeypadAccessoryButton2Command = "KEYPAD_ENTER";
KeypadAccessoryButton2Label = "Enter";
AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
index 0977dea2..8765b0e1 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
@@ -1,1257 +1,1279 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp.CrestronIO;
-using Crestron.SimplSharp.Ssh;
-using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharp;
-using PepperDash.Core;
-using PepperDash.Core.Intersystem;
-using PepperDash.Core.Intersystem.Tokens;
-using PepperDash.Core.WebApi.Presets;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-using PepperDash.Essentials.Core.Config;
-using PepperDash.Essentials.Core.Devices;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-using PepperDash.Essentials.Core.Routing;
-using PepperDash.Essentials.Devices.Common.Cameras;
-using PepperDash.Essentials.Devices.Common.Codec;
-using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
-using PepperDash_Essentials_Core.Bridges.JoinMaps;
-using PepperDash_Essentials_Core.DeviceTypeInterfaces;
-using Feedback = PepperDash.Essentials.Core.Feedback;
-
-namespace PepperDash.Essentials.Devices.Common.VideoCodec
-{
- public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs,
- IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
- {
- private const int XSigEncoding = 28591;
- private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
- protected VideoCodecBase(DeviceConfig config)
- : base(config)
- {
-
- StandbyIsOnFeedback = new BoolFeedback(StandbyIsOnFeedbackFunc);
- PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc);
- VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc);
- MuteFeedback = new BoolFeedback(MuteFeedbackFunc);
- SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc);
- SharingContentIsOnFeedback = new BoolFeedback(SharingContentIsOnFeedbackFunc);
-
- InputPorts = new RoutingPortCollection();
- OutputPorts = new RoutingPortCollection();
-
- ActiveCalls = new List();
- }
-
- public IBasicCommunication Communication { get; protected set; }
-
- ///
- /// An internal pseudo-source that is routable and connected to the osd input
- ///
- public DummyRoutingInputsDevice OsdSource { get; protected set; }
-
- public BoolFeedback StandbyIsOnFeedback { get; private set; }
-
- protected abstract Func PrivacyModeIsOnFeedbackFunc { get; }
- protected abstract Func VolumeLevelFeedbackFunc { get; }
- protected abstract Func MuteFeedbackFunc { get; }
- protected abstract Func StandbyIsOnFeedbackFunc { get; }
-
- public List ActiveCalls { get; set; }
-
- public bool ShowSelfViewByDefault { get; protected set; }
-
- protected bool SupportsCameraOff;
- protected bool SupportsCameraAutoMode;
-
- public bool IsReady { get; protected set; }
-
- public virtual List Feedbacks
- {
- get
- {
- return new List
- {
- PrivacyModeIsOnFeedback,
- SharingSourceFeedback
- };
- }
- }
-
- protected abstract Func SharingSourceFeedbackFunc { get; }
- protected abstract Func SharingContentIsOnFeedbackFunc { get; }
-
- #region ICodecAudio Members
-
- public abstract void PrivacyModeOn();
- public abstract void PrivacyModeOff();
- public abstract void PrivacyModeToggle();
- public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
-
-
- public BoolFeedback MuteFeedback { get; private set; }
-
- public abstract void MuteOff();
-
- public abstract void MuteOn();
-
- public abstract void SetVolume(ushort level);
-
- public IntFeedback VolumeLevelFeedback { get; private set; }
-
- public abstract void MuteToggle();
-
- public abstract void VolumeDown(bool pressRelease);
-
-
- public abstract void VolumeUp(bool pressRelease);
-
- #endregion
-
- #region IHasContentSharing Members
-
- public abstract void StartSharing();
- public abstract void StopSharing();
-
- public bool AutoShareContentWhileInCall { get; protected set; }
-
- public StringFeedback SharingSourceFeedback { get; private set; }
- public BoolFeedback SharingContentIsOnFeedback { get; private set; }
-
- #endregion
-
- #region IHasDialer Members
-
- ///
- /// Fires when the status of any active, dialing, or incoming call changes or is new
- ///
- public event EventHandler CallStatusChange;
-
- ///
- /// Returns true when any call is not in state Unknown, Disconnecting, Disconnected
- ///
- public bool IsInCall
- {
- get
- {
- var value = ActiveCalls != null && ActiveCalls.Any(c => c.IsActiveCall);
- return value;
- }
- }
-
- public abstract void Dial(string number);
- public abstract void EndCall(CodecActiveCallItem call);
- public abstract void EndAllCalls();
- public abstract void AcceptCall(CodecActiveCallItem call);
- public abstract void RejectCall(CodecActiveCallItem call);
- public abstract void SendDtmf(string s);
-
- #endregion
-
- #region IRoutingInputsOutputs Members
-
- public RoutingPortCollection InputPorts { get; private set; }
-
- public RoutingPortCollection OutputPorts { get; private set; }
-
- #endregion
-
- #region IUsageTracking Members
-
- ///
- /// This object can be added by outside users of this class to provide usage tracking
- /// for various services
- ///
- public UsageTracking UsageTracker { get; set; }
-
- #endregion
-
- #region iVideoCodecInfo Members
-
- public VideoCodecInfo CodecInfo { get; protected set; }
-
- #endregion
-
- public event EventHandler IsReadyChange;
- public abstract void Dial(Meeting meeting);
-
- public virtual void Dial(IInvitableContact contact)
- {
- }
-
- public abstract void ExecuteSwitch(object selector);
-
- ///
- /// Helper method to fire CallStatusChange event with old and new status
- ///
- protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call)
- {
- call.Status = newStatus;
-
- OnCallStatusChange(call);
- }
-
- ///
- ///
- ///
- ///
- ///
- ///
- protected virtual void OnCallStatusChange(CodecActiveCallItem item)
- {
- var handler = CallStatusChange;
- if (handler != null)
- {
- handler(this, new CodecCallStatusItemChangeEventArgs(item));
- }
-
- if (AutoShareContentWhileInCall)
- {
- StartSharing();
- }
-
- if (UsageTracker != null)
- {
- if (IsInCall && !UsageTracker.UsageTrackingStarted)
- {
- UsageTracker.StartDeviceUsage();
- }
- else if (UsageTracker.UsageTrackingStarted && !IsInCall)
- {
- UsageTracker.EndDeviceUsage();
- }
- }
- }
-
- ///
- /// Sets IsReady property and fires the event. Used for dependent classes to sync up their data.
- ///
- protected void SetIsReady()
- {
- CrestronInvoke.BeginInvoke( (o) =>
- {
- try
- {
- IsReady = true;
- var h = IsReadyChange;
- if (h != null)
- {
- h(this, new EventArgs());
- }
- }
- catch (Exception e)
- {
- Debug.Console(2, this, "Error in SetIsReady() : {0}", e);
- }
- });
- }
-
- // **** DEBUGGING THINGS ****
- ///
- ///
- ///
- public virtual void ListCalls()
- {
- var sb = new StringBuilder();
- foreach (var c in ActiveCalls)
- {
- sb.AppendFormat("{0} {1} -- {2} {3}\n", c.Id, c.Number, c.Name, c.Status);
- }
- Debug.Console(1, this, "\n{0}\n", sb.ToString());
- }
-
- public abstract void StandbyActivate();
-
- public abstract void StandbyDeactivate();
-
- #region Implementation of IBridgeAdvanced
-
- public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
-
- protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey,
- EiscApiAdvanced bridge)
- {
- var joinMap = new VideoCodecControllerJoinMap(joinStart);
-
- var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
-
- if (customJoins != null)
- {
- joinMap.SetCustomJoinData(customJoins);
- }
-
- if (bridge != null)
- {
- bridge.AddJoinMap(Key, joinMap);
- }
-
- Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X"));
-
-
-
- LinkVideoCodecDtmfToApi(trilist, joinMap);
-
- LinkVideoCodecCallControlsToApi(trilist, joinMap);
-
- LinkVideoCodecContentSharingToApi(trilist, joinMap);
-
- LinkVideoCodecPrivacyToApi(trilist, joinMap);
-
- LinkVideoCodecVolumeToApi(trilist, joinMap);
-
- if (codec is ICommunicationMonitor)
- {
- LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap);
- }
-
- if (codec is IHasCodecCameras)
- {
- LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap);
- }
-
- if (codec is IHasCodecSelfView)
- {
- LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap);
- }
-
- if (codec is IHasCameraAutoMode)
- {
- trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode);
- LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap);
- }
-
- if (codec is IHasCameraOff)
- {
- trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff);
- LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap);
- }
-
- if (codec is IHasCodecLayouts)
- {
- LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap);
- }
-
- if (codec is IHasSelfviewPosition)
- {
- LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap);
- }
-
- if (codec is IHasDirectory)
- {
- LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap);
- }
-
- if (codec is IHasScheduleAwareness)
- {
- LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap);
- }
-
- if (codec is IHasParticipants)
- {
- LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap);
- }
-
- if (codec is IHasFarEndContentStatus)
- {
- (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]);
- }
-
- if (codec is IHasPhoneDialing)
- {
- LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap);
- }
-
- trilist.OnlineStatusChange += (device, args) =>
- {
- if (!args.DeviceOnLine) return;
-
- if (codec is IHasDirectory)
- {
- (codec as IHasDirectory).SetCurrentDirectoryToRoot();
- }
-
- if (codec is IHasScheduleAwareness)
- {
- (codec as IHasScheduleAwareness).GetSchedule();
- }
-
- if (codec is IHasParticipants)
- {
- UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants);
- }
-
- if (codec is IHasCameraAutoMode)
- {
- trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true);
-
- (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
- }
-
- if (codec is IHasCodecSelfView)
- {
- (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate();
- }
-
- if (codec is IHasCameraAutoMode)
- {
- (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
- }
-
- if (codec is IHasCameraOff)
- {
- (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate();
- }
-
- if (codec is IHasPhoneDialing)
- {
- (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate();
- }
-
- SharingContentIsOnFeedback.FireUpdate();
-
- trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
-
- trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
- };
- }
-
- private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]);
-
- trilist.SetSigFalseAction(joinMap.DialPhone.JoinNumber,
- () => codec.DialPhoneCall(trilist.StringOutput[joinMap.PhoneDialString.JoinNumber].StringValue));
-
- trilist.SetSigFalseAction(joinMap.HangUpPhone.JoinNumber, codec.EndPhoneCall);
- }
-
- private void LinkVideoCodecSelfviewPositionToApi(IHasSelfviewPosition codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- trilist.SetSigFalseAction(joinMap.SelfviewPosition.JoinNumber, codec.SelfviewPipPositionToggle);
-
- codec.SelfviewPipPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.SelfviewPositionFb.JoinNumber]);
- }
-
- private void LinkVideoCodecCameraOffToApi(IHasCameraOff codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- trilist.SetSigFalseAction(joinMap.CameraModeOff.JoinNumber, codec.CameraOff);
-
- codec.CameraIsOffFeedback.OutputChange += (o, a) =>
- {
- if (a.BoolValue)
- {
- trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
- trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
- trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
- return;
- }
-
- trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
-
- var autoCodec = codec as IHasCameraAutoMode;
-
- if (autoCodec == null) return;
-
- trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
- trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
- };
-
- if (codec.CameraIsOffFeedback.BoolValue)
- {
- trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
- trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
- trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
- return;
- }
-
- trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
-
- var autoModeCodec = codec as IHasCameraAutoMode;
-
- if (autoModeCodec == null) return;
-
- trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
- trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
- }
-
- private void LinkVideoCodecVolumeToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
- MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
-
- trilist.SetSigFalseAction(joinMap.VolumeMuteOn.JoinNumber, MuteOn);
- trilist.SetSigFalseAction(joinMap.VolumeMuteOff.JoinNumber, MuteOff);
- trilist.SetSigFalseAction(joinMap.VolumeMuteToggle.JoinNumber, MuteToggle);
-
- VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
-
- trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, VolumeUp);
- trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, VolumeDown);
-
- trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, SetVolume);
-
- }
-
- private void LinkVideoCodecPrivacyToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- PrivacyModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.MicMuteOn.JoinNumber]);
- PrivacyModeIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.MicMuteOff.JoinNumber]);
-
- trilist.SetSigFalseAction(joinMap.MicMuteOn.JoinNumber, PrivacyModeOn);
- trilist.SetSigFalseAction(joinMap.MicMuteOff.JoinNumber, PrivacyModeOff);
- trilist.SetSigFalseAction(joinMap.MicMuteToggle.JoinNumber, PrivacyModeToggle);
- }
-
- private void LinkVideoCodecCommMonitorToApi(ICommunicationMonitor codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- codec.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
- }
-
- private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- codec.Participants.ParticipantsListHasChanged += (sender, args) =>
- {
- string participantsXSig;
-
- if (codec.Participants.CurrentParticipants.Count == 0)
- {
- participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length);
- trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
- trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
- return;
- }
-
- participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants);
-
- trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
-
- trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort) codec.Participants.CurrentParticipants.Count);
- };
- }
-
- private string UpdateParticipantsXSig(List currentParticipants)
- {
- const int maxParticipants = 50;
- const int maxDigitals = 5;
- const int maxStrings = 1;
- const int offset = maxDigitals + maxStrings;
- var digitalIndex = maxStrings * maxParticipants; //15
- var stringIndex = 0;
- var meetingIndex = 0;
-
- var tokenArray = new XSigToken[maxParticipants * offset];
-
- foreach (var participant in currentParticipants)
- {
- if (meetingIndex >= maxParticipants * offset) break;
-
- //digitals
- tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb);
- tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb);
- tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
- tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
- tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
-
- //serials
- tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
-
- digitalIndex += maxDigitals;
- meetingIndex += offset;
- stringIndex += maxStrings;
- }
-
- while (meetingIndex < maxParticipants*offset)
- {
- tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
- tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
- tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
- tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
- tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false);
-
- //serials
- tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
-
- digitalIndex += maxDigitals;
- meetingIndex += offset;
- stringIndex += maxStrings;
- }
-
- return GetXSigString(tokenArray);
- }
-
- private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]);
- SharingContentIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.SourceShareEnd.JoinNumber]);
-
- SharingSourceFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentSource.JoinNumber]);
-
- trilist.SetSigFalseAction(joinMap.SourceShareStart.JoinNumber, StartSharing);
- trilist.SetSigFalseAction(joinMap.SourceShareEnd.JoinNumber, StopSharing);
-
- trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b);
- }
-
- private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- trilist.SetSigFalseAction(joinMap.UpdateMeetings.JoinNumber, codec.GetSchedule);
-
- trilist.SetUShortSigAction(joinMap.MinutesBeforeMeetingStart.JoinNumber, (i) =>
- {
- codec.CodecSchedule.MeetingWarningMinutes = i;
- });
-
- codec.CodecSchedule.MeetingsListHasChanged += (sender, args) => UpdateMeetingsList(codec, trilist, joinMap);
-
- codec.CodecSchedule.MeetingEventChange +=
- (sender, args) =>
- {
- if (args.ChangeType == eMeetingEventChangeType.MeetingStartWarning)
- {
- UpdateMeetingsList(codec, trilist, joinMap);
- }
- };
- }
-
- private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- var currentTime = DateTime.Now;
- var currentMeetings =
- codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList();
-
- var meetingsData = UpdateMeetingsListXSig(currentMeetings);
-
- trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
-
- trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () =>
- {
- if(codec.CodecSchedule.Meetings[0] != null)
- Dial(codec.CodecSchedule.Meetings[0]);
- });
- trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () =>
- {
- if (codec.CodecSchedule.Meetings[1] != null)
- Dial(codec.CodecSchedule.Meetings[1]);
- });
- trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () =>
- {
- if (codec.CodecSchedule.Meetings[2] != null)
- Dial(codec.CodecSchedule.Meetings[2]);
- });
-
- trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)currentMeetings.Count);
- }
-
- private string UpdateMeetingsListXSig(List meetings)
- {
- const int maxMeetings = 3;
- const int maxDigitals = 2;
- const int maxStrings = 7;
- const int offset = maxDigitals + maxStrings;
- var digitalIndex = maxStrings*maxMeetings; //15
- var stringIndex = 0;
- var meetingIndex = 0;
-
- var tokenArray = new XSigToken[maxMeetings*offset];
- /*
- * Digitals
- * IsJoinable - 1
- * IsDialable - 2
- *
- * Serials
- * Organizer - 1
- * Title - 2
- * Start Date - 3
- * Start Time - 4
- * End Date - 5
- * End Time - 6
- */
-
-
- foreach(var meeting in meetings)
- {
- var currentTime = DateTime.Now;
-
- if(meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue;
-
- if (meetingIndex >= maxMeetings*offset)
- {
- Debug.Console(2, this, "Max Meetings reached");
- break;}
-
- //digitals
- tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable);
- tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Id != "0");
-
- //serials
- tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer);
- tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title);
- tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToShortDateString());
- tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToShortTimeString());
- tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToShortDateString());
- tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToShortTimeString());
- tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id);
-
-
- digitalIndex += maxDigitals;
- meetingIndex += offset;
- stringIndex += maxStrings;
- }
-
- while (meetingIndex < maxMeetings*offset)
- {
- Debug.Console(2, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}",
- meetingIndex, maxMeetings*offset);
-
- //digitals
- tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
- tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
-
- //serials
- tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
- tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty);
- tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty);
- tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty);
- tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty);
- tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty);
- tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, String.Empty);
-
- digitalIndex += maxDigitals;
- meetingIndex += offset;
- stringIndex += maxStrings;
- }
-
- return GetXSigString(tokenArray);
- }
-
- private void LinkVideoCodecDirectoryToApi(IHasDirectory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- codec.CurrentDirectoryResultIsNotDirectoryRoot.LinkComplementInputSig(
- trilist.BooleanInput[joinMap.DirectoryIsRoot.JoinNumber]);
-
- trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot);
-
- trilist.SetStringSigAction(joinMap.DirectorySearchString.JoinNumber, codec.SearchDirectory);
-
- trilist.SetUShortSigAction(joinMap.DirectorySelectRow.JoinNumber, (i) => SelectDirectoryEntry(codec, i));
-
- trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot);
-
- trilist.SetSigFalseAction(joinMap.DirectoryFolderBack.JoinNumber, codec.GetDirectoryParentFolderContents);
-
- codec.DirectoryResultReturned += (sender, args) =>
- {
- trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort) args.Directory.CurrentDirectoryResults.Count);
-
- var clearBytes = XSigHelpers.ClearOutputs();
-
- trilist.SetString(joinMap.DirectoryEntries.JoinNumber,
- Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length));
- var directoryXSig = UpdateDirectoryXSig(args.Directory, !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue);
-
- trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig);
- };
- }
-
- private void SelectDirectoryEntry(IHasDirectory codec, ushort i)
- {
- var entry = codec.CurrentDirectoryResult.CurrentDirectoryResults[i - 1];
-
- if (entry is DirectoryFolder)
- {
- codec.GetDirectoryFolderContents(entry.FolderId);
- return;
- }
-
- var dialableEntry = entry as IInvitableContact;
-
- if (dialableEntry != null)
- {
- Dial(dialableEntry);
- return;
- }
-
- var entryToDial = entry as DirectoryContact;
-
- if (entryToDial == null) return;
-
- Dial(entryToDial.ContactMethods[0].Number);
- }
-
- private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot)
- {
- var contactIndex = 1;
- var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count];
-
- foreach(var entry in directory.CurrentDirectoryResults)
- {
- var arrayIndex = contactIndex - 1;
-
- if (entry is DirectoryFolder && entry.ParentFolderId == "root")
- {
- tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, String.Format("[+] {0}", entry.Name));
-
- contactIndex++;
-
- continue;
- }
-
- if(isRoot && String.IsNullOrEmpty(entry.FolderId)) continue;
-
- tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, entry.Name);
-
- contactIndex++;
- }
-
- return GetXSigString(tokenArray);
- }
-
- private void LinkVideoCodecCallControlsToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- trilist.SetSigFalseAction(joinMap.ManualDial.JoinNumber,
- () => Dial(trilist.StringOutput[joinMap.CurrentDialString.JoinNumber].StringValue));
-
- //End All calls for now
- trilist.SetSigFalseAction(joinMap.EndCall.JoinNumber, EndAllCalls);
-
- trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
-
- CallStatusChange += (sender, args) =>
- {
- trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
-
- Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction);
- Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming);
- trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status != eCodecCallStatus.Disconnected);
-
- if (args.CallItem.Direction == eCodecCallDirection.Incoming)
- {
- trilist.SetSigFalseAction(joinMap.IncomingAnswer.JoinNumber, () => AcceptCall(args.CallItem));
- trilist.SetSigFalseAction(joinMap.IncomingReject.JoinNumber, () => RejectCall(args.CallItem));
- }
-
- trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
- };
- }
-
- private string UpdateCallStatusXSig()
- {
- const int maxCalls = 8;
- const int maxStrings = 5;
- const int offset = 6;
- var stringIndex = 0;
- var digitalIndex = maxStrings * maxCalls;
- var arrayIndex = 0;
-
- var tokenArray = new XSigToken[maxCalls*offset]; //set array size for number of calls * pieces of info
-
- foreach (var call in ActiveCalls)
- {
- if (arrayIndex >= maxCalls * offset)
- break;
- //digitals
- tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, call.IsActiveCall);
-
- //serials
- tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty);
- tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty);
- tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString());
- tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, call.Type.ToString());
- tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, call.Status.ToString());
-
- arrayIndex += offset;
- stringIndex += maxStrings;
- digitalIndex++;
- }
- while (digitalIndex < maxCalls)
- {
- //digitals
- tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, false);
-
- //serials
- tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, String.Empty);
- tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, String.Empty);
- tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, String.Empty);
- tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, String.Empty);
- tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, String.Empty);
-
- arrayIndex += offset;
- stringIndex += maxStrings;
- digitalIndex++;
- }
-
- return GetXSigString(tokenArray);
- }
-
- private void LinkVideoCodecDtmfToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- trilist.SetSigFalseAction(joinMap.Dtmf0.JoinNumber, () => SendDtmf("0"));
- trilist.SetSigFalseAction(joinMap.Dtmf1.JoinNumber, () => SendDtmf("1"));
- trilist.SetSigFalseAction(joinMap.Dtmf2.JoinNumber, () => SendDtmf("2"));
- trilist.SetSigFalseAction(joinMap.Dtmf3.JoinNumber, () => SendDtmf("3"));
- trilist.SetSigFalseAction(joinMap.Dtmf4.JoinNumber, () => SendDtmf("4"));
- trilist.SetSigFalseAction(joinMap.Dtmf5.JoinNumber, () => SendDtmf("5"));
- trilist.SetSigFalseAction(joinMap.Dtmf6.JoinNumber, () => SendDtmf("6"));
- trilist.SetSigFalseAction(joinMap.Dtmf7.JoinNumber, () => SendDtmf("7"));
- trilist.SetSigFalseAction(joinMap.Dtmf8.JoinNumber, () => SendDtmf("8"));
- trilist.SetSigFalseAction(joinMap.Dtmf9.JoinNumber, () => SendDtmf("9"));
- trilist.SetSigFalseAction(joinMap.DtmfStar.JoinNumber, () => SendDtmf("*"));
- trilist.SetSigFalseAction(joinMap.DtmfPound.JoinNumber, () => SendDtmf("#"));
- }
-
- private void LinkVideoCodecCameraLayoutsToApi(IHasCodecLayouts codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- trilist.SetSigFalseAction(joinMap.CameraLayout.JoinNumber, codec.LocalLayoutToggle);
-
- codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CameraLayoutStringFb.JoinNumber]);
- }
-
- private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn);
- trilist.SetSigFalseAction(joinMap.CameraModeManual.JoinNumber, codec.CameraAutoModeOff);
-
- codec.CameraAutoModeIsOnFeedback.OutputChange += (o, a) =>
- {
- var offCodec = codec as IHasCameraOff;
-
- if (offCodec != null)
- {
- if (offCodec.CameraIsOffFeedback.BoolValue)
- {
- trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
- trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
- trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
- return;
- }
-
- trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
- trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
- trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
- return;
- }
-
- trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
- trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
- trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
- };
-
- var offModeCodec = codec as IHasCameraOff;
-
- if (offModeCodec != null)
- {
- if (offModeCodec.CameraIsOffFeedback.BoolValue)
- {
- trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
- trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
- trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
- return;
- }
-
- trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
- trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
- trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
- return;
- }
-
- trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
- trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
- trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
- }
-
- private void LinkVideoCodecSelfviewToApi(IHasCodecSelfView codec, BasicTriList trilist,
- VideoCodecControllerJoinMap joinMap)
- {
- trilist.SetSigFalseAction(joinMap.CameraSelfView.JoinNumber, codec.SelfViewModeToggle);
-
- codec.SelfviewIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CameraSelfView.JoinNumber]);
- }
-
- private void LinkVideoCodecCameraToApi(IHasCodecCameras codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
- {
- //Camera PTZ
- trilist.SetBoolSigAction(joinMap.CameraTiltUp.JoinNumber, (b) =>
- {
- if (codec.SelectedCamera == null) return;
- var camera = codec.SelectedCamera as IHasCameraPtzControl;
-
- if (camera == null) return;
-
- if (b) camera.TiltUp();
- else camera.TiltStop();
- });
-
- trilist.SetBoolSigAction(joinMap.CameraTiltDown.JoinNumber, (b) =>
- {
- if (codec.SelectedCamera == null) return;
- var camera = codec.SelectedCamera as IHasCameraPtzControl;
-
- if (camera == null) return;
-
- if (b) camera.TiltDown();
- else camera.TiltStop();
- });
- trilist.SetBoolSigAction(joinMap.CameraPanLeft.JoinNumber, (b) =>
- {
- if (codec.SelectedCamera == null) return;
- var camera = codec.SelectedCamera as IHasCameraPtzControl;
-
- if (camera == null) return;
-
- if (b) camera.PanLeft();
- else camera.PanStop();
- });
- trilist.SetBoolSigAction(joinMap.CameraPanRight.JoinNumber, (b) =>
- {
- if (codec.SelectedCamera == null) return;
- var camera = codec.SelectedCamera as IHasCameraPtzControl;
-
- if (camera == null) return;
-
- if (b) camera.PanRight();
- else camera.PanStop();
- });
-
- trilist.SetBoolSigAction(joinMap.CameraZoomIn.JoinNumber, (b) =>
- {
- if (codec.SelectedCamera == null) return;
- var camera = codec.SelectedCamera as IHasCameraPtzControl;
-
- if (camera == null) return;
-
- if (b) camera.ZoomIn();
- else camera.ZoomStop();
- });
-
- trilist.SetBoolSigAction(joinMap.CameraZoomOut.JoinNumber, (b) =>
- {
- if (codec.SelectedCamera == null) return;
- var camera = codec.SelectedCamera as IHasCameraPtzControl;
-
- if (camera == null) return;
-
- if (b) camera.ZoomOut();
- else camera.ZoomStop();
- });
-
- //Camera Select
- trilist.SetUShortSigAction(joinMap.CameraNumberSelect.JoinNumber, (i) =>
- {
- if (codec.SelectedCamera == null) return;
-
- codec.SelectCamera(codec.Cameras[i].Key);
- });
-
- codec.CameraSelected += (sender, args) =>
- {
- var i = (ushort) codec.Cameras.FindIndex((c) => c.Key == args.SelectedCamera.Key);
-
- if (codec is IHasCodecRoomPresets)
- {
- return;
- }
-
- if (!(args.SelectedCamera is IHasCameraPresets))
- {
- return;
- }
-
- var cam = args.SelectedCamera as IHasCameraPresets;
- SetCameraPresetNames(cam.Presets);
-
- (args.SelectedCamera as IHasCameraPresets).PresetsListHasChanged += (o, eventArgs) => SetCameraPresetNames(cam.Presets);
-
- trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber,
- (a) =>
- {
- cam.PresetSelect(a);
- trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, a);
- });
-
- trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber,
- () =>
- {
- cam.PresetStore(trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue,
- String.Empty);
- trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000);
- });
- };
-
- if (!(codec is IHasCodecRoomPresets)) return;
-
- var presetCodec = codec as IHasCodecRoomPresets;
-
- presetCodec.CodecRoomPresetsListHasChanged +=
- (sender, args) => SetCameraPresetNames(presetCodec.NearEndPresets);
-
- //Camera Presets
- trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, (i) =>
- {
- presetCodec.CodecRoomPresetSelect(i);
-
- trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, i);
- });
-
- trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber,
- () =>
- {
- presetCodec.CodecRoomPresetStore(
- trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, String.Empty);
- trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000);
- });
- }
-
- private string SetCameraPresetNames(IEnumerable presets)
- {
- return SetCameraPresetNames(presets.Select(p => p.Description).ToList());
- }
-
- private string SetCameraPresetNames(IEnumerable presets)
- {
- return SetCameraPresetNames(presets.Select(p => p.Description).ToList());
- }
-
- private string SetCameraPresetNames(ICollection presets)
- {
- var i = 1; //start index for xsig;
-
- var tokenArray = new XSigToken[presets.Count];
-
- foreach (var preset in presets)
- {
- var cameraPreset = new XSigSerialToken(i, preset);
- tokenArray[i - 1] = cameraPreset;
- i++;
- }
-
- return GetXSigString(tokenArray);
- }
-
- private string GetXSigString(XSigToken[] tokenArray)
- {
- string returnString;
- using (var s = new MemoryStream())
- {
- using (var tw = new XSigTokenStreamWriter(s, true))
- {
- tw.WriteXSigData(tokenArray);
- }
-
- var xSig = s.ToArray();
-
- returnString = Encoding.GetEncoding(XSigEncoding).GetString(xSig, 0, xSig.Length);
- }
-
- return returnString;
- }
-
- #endregion
- }
-
-
- ///
- /// Used to track the status of syncronizing the phonebook values when connecting to a codec or refreshing the phonebook info
- ///
- public class CodecPhonebookSyncState : IKeyed
- {
- private bool _InitialSyncComplete;
-
- public CodecPhonebookSyncState(string key)
- {
- Key = key;
-
- CodecDisconnected();
- }
-
- public bool InitialSyncComplete
- {
- get { return _InitialSyncComplete; }
- private set
- {
- if (value == true)
- {
- var handler = InitialSyncCompleted;
- if (handler != null)
- {
- handler(this, new EventArgs());
- }
- }
- _InitialSyncComplete = value;
- }
- }
-
- public bool InitialPhonebookFoldersWasReceived { get; private set; }
-
- public bool NumberOfContactsWasReceived { get; private set; }
-
- public bool PhonebookRootEntriesWasRecieved { get; private set; }
-
- public bool PhonebookHasFolders { get; private set; }
-
- public int NumberOfContacts { get; private set; }
-
- #region IKeyed Members
-
- public string Key { get; private set; }
-
- #endregion
-
- public event EventHandler InitialSyncCompleted;
-
- public void InitialPhonebookFoldersReceived()
- {
- InitialPhonebookFoldersWasReceived = true;
-
- CheckSyncStatus();
- }
-
- public void PhonebookRootEntriesReceived()
- {
- PhonebookRootEntriesWasRecieved = true;
-
- CheckSyncStatus();
- }
-
- public void SetPhonebookHasFolders(bool value)
- {
- PhonebookHasFolders = value;
-
- Debug.Console(1, this, "Phonebook has folders: {0}", PhonebookHasFolders);
- }
-
- public void SetNumberOfContacts(int contacts)
- {
- NumberOfContacts = contacts;
- NumberOfContactsWasReceived = true;
-
- Debug.Console(1, this, "Phonebook contains {0} contacts.", NumberOfContacts);
-
- CheckSyncStatus();
- }
-
- public void CodecDisconnected()
- {
- InitialPhonebookFoldersWasReceived = false;
- PhonebookHasFolders = false;
- NumberOfContacts = 0;
- NumberOfContactsWasReceived = false;
- }
-
- private void CheckSyncStatus()
- {
- if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved)
- {
- InitialSyncComplete = true;
- Debug.Console(1, this, "Initial Phonebook Sync Complete!");
- }
- else
- {
- InitialSyncComplete = false;
- }
- }
- }
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp.CrestronIO;
+using Crestron.SimplSharp.Ssh;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharp;
+using PepperDash.Core;
+using PepperDash.Core.Intersystem;
+using PepperDash.Core.Intersystem.Tokens;
+using PepperDash.Core.WebApi.Presets;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+using PepperDash.Essentials.Core.Config;
+using PepperDash.Essentials.Core.Devices;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Core.Routing;
+using PepperDash.Essentials.Devices.Common.Cameras;
+using PepperDash.Essentials.Devices.Common.Codec;
+using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
+using PepperDash_Essentials_Core.Bridges.JoinMaps;
+using PepperDash_Essentials_Core.DeviceTypeInterfaces;
+using Feedback = PepperDash.Essentials.Core.Feedback;
+
+namespace PepperDash.Essentials.Devices.Common.VideoCodec
+{
+ public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs,
+ IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
+ {
+ private const int XSigEncoding = 28591;
+ private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
+ protected VideoCodecBase(DeviceConfig config)
+ : base(config)
+ {
+
+ StandbyIsOnFeedback = new BoolFeedback(StandbyIsOnFeedbackFunc);
+ PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc);
+ VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc);
+ MuteFeedback = new BoolFeedback(MuteFeedbackFunc);
+ SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc);
+ SharingContentIsOnFeedback = new BoolFeedback(SharingContentIsOnFeedbackFunc);
+
+ InputPorts = new RoutingPortCollection();
+ OutputPorts = new RoutingPortCollection();
+
+ ActiveCalls = new List();
+ }
+
+ public IBasicCommunication Communication { get; protected set; }
+
+ ///
+ /// An internal pseudo-source that is routable and connected to the osd input
+ ///
+ public DummyRoutingInputsDevice OsdSource { get; protected set; }
+
+ public BoolFeedback StandbyIsOnFeedback { get; private set; }
+
+ protected abstract Func PrivacyModeIsOnFeedbackFunc { get; }
+ protected abstract Func VolumeLevelFeedbackFunc { get; }
+ protected abstract Func MuteFeedbackFunc { get; }
+ protected abstract Func StandbyIsOnFeedbackFunc { get; }
+
+ public List ActiveCalls { get; set; }
+
+ public bool ShowSelfViewByDefault { get; protected set; }
+
+ protected bool SupportsCameraOff;
+ protected bool SupportsCameraAutoMode;
+
+ public bool IsReady { get; protected set; }
+
+ public virtual List Feedbacks
+ {
+ get
+ {
+ return new List
+ {
+ PrivacyModeIsOnFeedback,
+ SharingSourceFeedback
+ };
+ }
+ }
+
+ protected abstract Func SharingSourceFeedbackFunc { get; }
+ protected abstract Func SharingContentIsOnFeedbackFunc { get; }
+
+ #region ICodecAudio Members
+
+ public abstract void PrivacyModeOn();
+ public abstract void PrivacyModeOff();
+ public abstract void PrivacyModeToggle();
+ public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
+
+
+ public BoolFeedback MuteFeedback { get; private set; }
+
+ public abstract void MuteOff();
+
+ public abstract void MuteOn();
+
+ public abstract void SetVolume(ushort level);
+
+ public IntFeedback VolumeLevelFeedback { get; private set; }
+
+ public abstract void MuteToggle();
+
+ public abstract void VolumeDown(bool pressRelease);
+
+
+ public abstract void VolumeUp(bool pressRelease);
+
+ #endregion
+
+ #region IHasContentSharing Members
+
+ public abstract void StartSharing();
+ public abstract void StopSharing();
+
+ public bool AutoShareContentWhileInCall { get; protected set; }
+
+ public StringFeedback SharingSourceFeedback { get; private set; }
+ public BoolFeedback SharingContentIsOnFeedback { get; private set; }
+
+ #endregion
+
+ #region IHasDialer Members
+
+ ///
+ /// Fires when the status of any active, dialing, or incoming call changes or is new
+ ///
+ public event EventHandler CallStatusChange;
+
+ ///
+ /// Returns true when any call is not in state Unknown, Disconnecting, Disconnected
+ ///
+ public bool IsInCall
+ {
+ get
+ {
+ var value = ActiveCalls != null && ActiveCalls.Any(c => c.IsActiveCall);
+ return value;
+ }
+ }
+
+ public abstract void Dial(string number);
+ public abstract void EndCall(CodecActiveCallItem call);
+ public abstract void EndAllCalls();
+ public abstract void AcceptCall(CodecActiveCallItem call);
+ public abstract void RejectCall(CodecActiveCallItem call);
+ public abstract void SendDtmf(string s);
+
+ #endregion
+
+ #region IRoutingInputsOutputs Members
+
+ public RoutingPortCollection InputPorts { get; private set; }
+
+ public RoutingPortCollection OutputPorts { get; private set; }
+
+ #endregion
+
+ #region IUsageTracking Members
+
+ ///
+ /// This object can be added by outside users of this class to provide usage tracking
+ /// for various services
+ ///
+ public UsageTracking UsageTracker { get; set; }
+
+ #endregion
+
+ #region iVideoCodecInfo Members
+
+ public VideoCodecInfo CodecInfo { get; protected set; }
+
+ #endregion
+
+ public event EventHandler IsReadyChange;
+ public abstract void Dial(Meeting meeting);
+
+ public virtual void Dial(IInvitableContact contact)
+ {
+ }
+
+ public abstract void ExecuteSwitch(object selector);
+
+ ///
+ /// Helper method to fire CallStatusChange event with old and new status
+ ///
+ protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call)
+ {
+ call.Status = newStatus;
+
+ OnCallStatusChange(call);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected virtual void OnCallStatusChange(CodecActiveCallItem item)
+ {
+ var handler = CallStatusChange;
+ if (handler != null)
+ {
+ handler(this, new CodecCallStatusItemChangeEventArgs(item));
+ }
+
+ if (AutoShareContentWhileInCall)
+ {
+ StartSharing();
+ }
+
+ if (UsageTracker != null)
+ {
+ if (IsInCall && !UsageTracker.UsageTrackingStarted)
+ {
+ UsageTracker.StartDeviceUsage();
+ }
+ else if (UsageTracker.UsageTrackingStarted && !IsInCall)
+ {
+ UsageTracker.EndDeviceUsage();
+ }
+ }
+ }
+
+ ///
+ /// Sets IsReady property and fires the event. Used for dependent classes to sync up their data.
+ ///
+ protected void SetIsReady()
+ {
+ CrestronInvoke.BeginInvoke((o) =>
+ {
+ try
+ {
+ IsReady = true;
+ var h = IsReadyChange;
+ if (h != null)
+ {
+ h(this, new EventArgs());
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.Console(2, this, "Error in SetIsReady() : {0}", e);
+ }
+ });
+ }
+
+ // **** DEBUGGING THINGS ****
+ ///
+ ///
+ ///
+ public virtual void ListCalls()
+ {
+ var sb = new StringBuilder();
+ foreach (var c in ActiveCalls)
+ {
+ sb.AppendFormat("{0} {1} -- {2} {3}\n", c.Id, c.Number, c.Name, c.Status);
+ }
+ Debug.Console(1, this, "\n{0}\n", sb.ToString());
+ }
+
+ public abstract void StandbyActivate();
+
+ public abstract void StandbyDeactivate();
+
+ #region Implementation of IBridgeAdvanced
+
+ public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
+
+ protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey,
+ EiscApiAdvanced bridge)
+ {
+ var joinMap = new VideoCodecControllerJoinMap(joinStart);
+
+ var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
+
+ if (customJoins != null)
+ {
+ joinMap.SetCustomJoinData(customJoins);
+ }
+
+ if (bridge != null)
+ {
+ bridge.AddJoinMap(Key, joinMap);
+ }
+
+ Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X"));
+
+
+
+ LinkVideoCodecDtmfToApi(trilist, joinMap);
+
+ LinkVideoCodecCallControlsToApi(trilist, joinMap);
+
+ LinkVideoCodecContentSharingToApi(trilist, joinMap);
+
+ LinkVideoCodecPrivacyToApi(trilist, joinMap);
+
+ LinkVideoCodecVolumeToApi(trilist, joinMap);
+
+ if (codec is ICommunicationMonitor)
+ {
+ LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap);
+ }
+
+ if (codec is IHasCodecCameras)
+ {
+ LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap);
+ }
+
+ if (codec is IHasCodecSelfView)
+ {
+ LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap);
+ }
+
+ if (codec is IHasCameraAutoMode)
+ {
+ trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode);
+ LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap);
+ }
+
+ if (codec is IHasCameraOff)
+ {
+ trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff);
+ LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap);
+ }
+
+ if (codec is IHasCodecLayouts)
+ {
+ LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap);
+ }
+
+ if (codec is IHasSelfviewPosition)
+ {
+ LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap);
+ }
+
+ if (codec is IHasDirectory)
+ {
+ LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap);
+ }
+
+ if (codec is IHasScheduleAwareness)
+ {
+ LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap);
+ }
+
+ if (codec is IHasParticipants)
+ {
+ LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap);
+ }
+
+ if (codec is IHasFarEndContentStatus)
+ {
+ (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]);
+ }
+
+ if (codec is IHasPhoneDialing)
+ {
+ LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap);
+ }
+
+ trilist.OnlineStatusChange += (device, args) =>
+ {
+ if (!args.DeviceOnLine) return;
+
+ if (codec is IHasDirectory)
+ {
+ (codec as IHasDirectory).SetCurrentDirectoryToRoot();
+ }
+
+ if (codec is IHasScheduleAwareness)
+ {
+ (codec as IHasScheduleAwareness).GetSchedule();
+ }
+
+ if (codec is IHasParticipants)
+ {
+ UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants);
+ }
+
+ if (codec is IHasCameraAutoMode)
+ {
+ trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true);
+
+ (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
+ }
+
+ if (codec is IHasCodecSelfView)
+ {
+ (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate();
+ }
+
+ if (codec is IHasCameraAutoMode)
+ {
+ (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
+ }
+
+ if (codec is IHasCameraOff)
+ {
+ (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate();
+ }
+
+ if (codec is IHasPhoneDialing)
+ {
+ (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate();
+ }
+
+ SharingContentIsOnFeedback.FireUpdate();
+
+ trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
+
+ trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
+ };
+ }
+
+ private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.DialPhone.JoinNumber,
+ () => codec.DialPhoneCall(trilist.StringOutput[joinMap.PhoneDialString.JoinNumber].StringValue));
+
+ trilist.SetSigFalseAction(joinMap.HangUpPhone.JoinNumber, codec.EndPhoneCall);
+ }
+
+ private void LinkVideoCodecSelfviewPositionToApi(IHasSelfviewPosition codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.SelfviewPosition.JoinNumber, codec.SelfviewPipPositionToggle);
+
+ codec.SelfviewPipPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.SelfviewPositionFb.JoinNumber]);
+ }
+
+ private void LinkVideoCodecCameraOffToApi(IHasCameraOff codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.CameraModeOff.JoinNumber, codec.CameraOff);
+
+ codec.CameraIsOffFeedback.OutputChange += (o, a) =>
+ {
+ if (a.BoolValue)
+ {
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+
+ var autoCodec = codec as IHasCameraAutoMode;
+
+ if (autoCodec == null) return;
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
+ };
+
+ if (codec.CameraIsOffFeedback.BoolValue)
+ {
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+
+ var autoModeCodec = codec as IHasCameraAutoMode;
+
+ if (autoModeCodec == null) return;
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
+ }
+
+ private void LinkVideoCodecVolumeToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
+ MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.VolumeMuteOn.JoinNumber, MuteOn);
+ trilist.SetSigFalseAction(joinMap.VolumeMuteOff.JoinNumber, MuteOff);
+ trilist.SetSigFalseAction(joinMap.VolumeMuteToggle.JoinNumber, MuteToggle);
+
+ VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
+
+ trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, VolumeUp);
+ trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, VolumeDown);
+
+ trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, SetVolume);
+
+ }
+
+ private void LinkVideoCodecPrivacyToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ PrivacyModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.MicMuteOn.JoinNumber]);
+ PrivacyModeIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.MicMuteOff.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.MicMuteOn.JoinNumber, PrivacyModeOn);
+ trilist.SetSigFalseAction(joinMap.MicMuteOff.JoinNumber, PrivacyModeOff);
+ trilist.SetSigFalseAction(joinMap.MicMuteToggle.JoinNumber, PrivacyModeToggle);
+ }
+
+ private void LinkVideoCodecCommMonitorToApi(ICommunicationMonitor codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ codec.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
+ }
+
+ private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ codec.Participants.ParticipantsListHasChanged += (sender, args) =>
+ {
+ string participantsXSig;
+
+ if (codec.Participants.CurrentParticipants.Count == 0)
+ {
+ participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length);
+ trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
+ trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
+ return;
+ }
+
+ participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants);
+
+ trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
+
+ trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
+ };
+ }
+
+ private string UpdateParticipantsXSig(List currentParticipants)
+ {
+ const int maxParticipants = 50;
+ const int maxDigitals = 5;
+ const int maxStrings = 1;
+ const int offset = maxDigitals + maxStrings;
+ var digitalIndex = maxStrings * maxParticipants; //15
+ var stringIndex = 0;
+ var meetingIndex = 0;
+
+ var tokenArray = new XSigToken[maxParticipants * offset];
+
+ foreach (var participant in currentParticipants)
+ {
+ if (meetingIndex >= maxParticipants * offset) break;
+
+ //digitals
+ tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb);
+ tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb);
+ tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
+ tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
+ tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
+
+ //serials
+ tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
+
+ digitalIndex += maxDigitals;
+ meetingIndex += offset;
+ stringIndex += maxStrings;
+ }
+
+ while (meetingIndex < maxParticipants * offset)
+ {
+ tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
+ tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
+ tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
+ tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
+ tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false);
+
+ //serials
+ tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
+
+ digitalIndex += maxDigitals;
+ meetingIndex += offset;
+ stringIndex += maxStrings;
+ }
+
+ return GetXSigString(tokenArray);
+ }
+
+ private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]);
+ SharingContentIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.SourceShareEnd.JoinNumber]);
+
+ SharingSourceFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentSource.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.SourceShareStart.JoinNumber, StartSharing);
+ trilist.SetSigFalseAction(joinMap.SourceShareEnd.JoinNumber, StopSharing);
+
+ trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b);
+ }
+
+ // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
+ private List _currentMeetings = new List();
+
+ private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.UpdateMeetings.JoinNumber, codec.GetSchedule);
+
+ trilist.SetUShortSigAction(joinMap.MinutesBeforeMeetingStart.JoinNumber, (i) =>
+ {
+ codec.CodecSchedule.MeetingWarningMinutes = i;
+ });
+
+ // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
+ trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () =>
+ {
+ var mtg = 1;
+ var index = mtg - 1;
+ Debug.Console(1, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}",
+ mtg, joinMap.DialMeeting1.JoinNumber, index, _currentMeetings[index].Id, _currentMeetings[index].Title);
+ if (_currentMeetings[index] != null)
+ Dial(_currentMeetings[index]);
+ });
+ // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
+ trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () =>
+ {
+ var mtg = 2;
+ var index = mtg - 1;
+ Debug.Console(1, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}",
+ mtg, joinMap.DialMeeting2.JoinNumber, index, _currentMeetings[index].Id, _currentMeetings[index].Title);
+ if (_currentMeetings[index] != null)
+ Dial(_currentMeetings[index]);
+ });
+ // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
+ trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () =>
+ {
+ var mtg = 3;
+ var index = mtg - 1;
+ Debug.Console(1, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}",
+ mtg, joinMap.DialMeeting3.JoinNumber, index, _currentMeetings[index].Id, _currentMeetings[index].Title);
+ if (_currentMeetings[index] != null)
+ Dial(_currentMeetings[index]);
+ });
+
+ codec.CodecSchedule.MeetingsListHasChanged += (sender, args) => UpdateMeetingsList(codec, trilist, joinMap);
+ codec.CodecSchedule.MeetingEventChange += (sender, args) =>
+ {
+ if (args.ChangeType == eMeetingEventChangeType.MeetingStartWarning)
+ {
+ UpdateMeetingsList(codec, trilist, joinMap);
+ }
+ };
+ }
+
+ private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ var currentTime = DateTime.Now;
+
+ // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
+ // - changed var currentMeetings >> field _currentMeetings
+ //_currentMeetings.Clear();
+ _currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList();
+
+ // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
+ // - moved the trilist.SetSigFlaseAction(joinMap.DialMeeting1..3.JoinNumber) lambda's to LinkVideoCodecScheduleToApi
+
+ var meetingsData = UpdateMeetingsListXSig(_currentMeetings);
+ trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
+ trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count);
+ }
+
+ private string UpdateMeetingsListXSig(List meetings)
+ {
+ const int maxMeetings = 3;
+ const int maxDigitals = 2;
+ const int maxStrings = 7;
+ const int offset = maxDigitals + maxStrings;
+ var digitalIndex = maxStrings * maxMeetings; //15
+ var stringIndex = 0;
+ var meetingIndex = 0;
+
+ var tokenArray = new XSigToken[maxMeetings * offset];
+ /*
+ * Digitals
+ * IsJoinable - 1
+ * IsDialable - 2
+ *
+ * Serials
+ * Organizer - 1
+ * Title - 2
+ * Start Date - 3
+ * Start Time - 4
+ * End Date - 5
+ * End Time - 6
+ * Id - 7
+ */
+
+
+ foreach (var meeting in meetings)
+ {
+ var currentTime = DateTime.Now;
+
+ if (meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue;
+
+ if (meetingIndex >= maxMeetings * offset)
+ {
+ Debug.Console(2, this, "Max Meetings reached");
+ break;
+ }
+
+ //digitals
+ tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable);
+ tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Id != "0");
+
+ //serials
+ tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer);
+ tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title);
+ tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToShortDateString());
+ tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToShortTimeString());
+ tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToShortDateString());
+ tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToShortTimeString());
+ tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id);
+
+
+ digitalIndex += maxDigitals;
+ meetingIndex += offset;
+ stringIndex += maxStrings;
+ }
+
+ while (meetingIndex < maxMeetings * offset)
+ {
+ Debug.Console(2, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}",
+ meetingIndex, maxMeetings * offset);
+
+ //digitals
+ tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
+ tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
+
+ //serials
+ tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
+ tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty);
+ tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty);
+ tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty);
+ tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty);
+ tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty);
+ tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, String.Empty);
+
+ digitalIndex += maxDigitals;
+ meetingIndex += offset;
+ stringIndex += maxStrings;
+ }
+
+ return GetXSigString(tokenArray);
+ }
+
+ private void LinkVideoCodecDirectoryToApi(IHasDirectory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ codec.CurrentDirectoryResultIsNotDirectoryRoot.LinkComplementInputSig(
+ trilist.BooleanInput[joinMap.DirectoryIsRoot.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot);
+
+ trilist.SetStringSigAction(joinMap.DirectorySearchString.JoinNumber, codec.SearchDirectory);
+
+ trilist.SetUShortSigAction(joinMap.DirectorySelectRow.JoinNumber, (i) => SelectDirectoryEntry(codec, i));
+
+ trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot);
+
+ trilist.SetSigFalseAction(joinMap.DirectoryFolderBack.JoinNumber, codec.GetDirectoryParentFolderContents);
+
+ codec.DirectoryResultReturned += (sender, args) =>
+ {
+ trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort)args.Directory.CurrentDirectoryResults.Count);
+
+ var clearBytes = XSigHelpers.ClearOutputs();
+
+ trilist.SetString(joinMap.DirectoryEntries.JoinNumber,
+ Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length));
+ var directoryXSig = UpdateDirectoryXSig(args.Directory, !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue);
+
+ trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig);
+ };
+ }
+
+ private void SelectDirectoryEntry(IHasDirectory codec, ushort i)
+ {
+ var entry = codec.CurrentDirectoryResult.CurrentDirectoryResults[i - 1];
+
+ if (entry is DirectoryFolder)
+ {
+ codec.GetDirectoryFolderContents(entry.FolderId);
+ return;
+ }
+
+ var dialableEntry = entry as IInvitableContact;
+
+ if (dialableEntry != null)
+ {
+ Dial(dialableEntry);
+ return;
+ }
+
+ var entryToDial = entry as DirectoryContact;
+
+ if (entryToDial == null) return;
+
+ Dial(entryToDial.ContactMethods[0].Number);
+ }
+
+ private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot)
+ {
+ var contactIndex = 1;
+ var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count];
+
+ foreach (var entry in directory.CurrentDirectoryResults)
+ {
+ var arrayIndex = contactIndex - 1;
+
+ if (entry is DirectoryFolder && entry.ParentFolderId == "root")
+ {
+ tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, String.Format("[+] {0}", entry.Name));
+
+ contactIndex++;
+
+ continue;
+ }
+
+ if (isRoot && String.IsNullOrEmpty(entry.FolderId)) continue;
+
+ tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, entry.Name);
+
+ contactIndex++;
+ }
+
+ return GetXSigString(tokenArray);
+ }
+
+ private void LinkVideoCodecCallControlsToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.ManualDial.JoinNumber,
+ () => Dial(trilist.StringOutput[joinMap.CurrentDialString.JoinNumber].StringValue));
+
+ //End All calls for now
+ trilist.SetSigFalseAction(joinMap.EndCall.JoinNumber, EndAllCalls);
+
+ trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
+
+ CallStatusChange += (sender, args) =>
+ {
+ trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
+
+ Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction);
+ Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming);
+ trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status == eCodecCallStatus.Ringing);
+
+ if (args.CallItem.Direction == eCodecCallDirection.Incoming)
+ {
+ trilist.SetSigFalseAction(joinMap.IncomingAnswer.JoinNumber, () => AcceptCall(args.CallItem));
+ trilist.SetSigFalseAction(joinMap.IncomingReject.JoinNumber, () => RejectCall(args.CallItem));
+ }
+
+ trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
+ };
+ }
+
+ private string UpdateCallStatusXSig()
+ {
+ const int maxCalls = 8;
+ const int maxStrings = 5;
+ const int offset = 6;
+ var stringIndex = 0;
+ var digitalIndex = maxStrings * maxCalls;
+ var arrayIndex = 0;
+
+ var tokenArray = new XSigToken[maxCalls * offset]; //set array size for number of calls * pieces of info
+
+ foreach (var call in ActiveCalls)
+ {
+ if (arrayIndex >= maxCalls * offset)
+ break;
+ //digitals
+ tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, call.IsActiveCall);
+
+ //serials
+ tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty);
+ tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty);
+ tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString());
+ tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, call.Type.ToString());
+ tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, call.Status.ToString());
+
+ arrayIndex += offset;
+ stringIndex += maxStrings;
+ digitalIndex++;
+ }
+ while (digitalIndex < maxCalls)
+ {
+ //digitals
+ tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, false);
+
+ //serials
+ tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, String.Empty);
+ tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, String.Empty);
+ tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, String.Empty);
+ tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, String.Empty);
+ tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, String.Empty);
+
+ arrayIndex += offset;
+ stringIndex += maxStrings;
+ digitalIndex++;
+ }
+
+ return GetXSigString(tokenArray);
+ }
+
+ private void LinkVideoCodecDtmfToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.Dtmf0.JoinNumber, () => SendDtmf("0"));
+ trilist.SetSigFalseAction(joinMap.Dtmf1.JoinNumber, () => SendDtmf("1"));
+ trilist.SetSigFalseAction(joinMap.Dtmf2.JoinNumber, () => SendDtmf("2"));
+ trilist.SetSigFalseAction(joinMap.Dtmf3.JoinNumber, () => SendDtmf("3"));
+ trilist.SetSigFalseAction(joinMap.Dtmf4.JoinNumber, () => SendDtmf("4"));
+ trilist.SetSigFalseAction(joinMap.Dtmf5.JoinNumber, () => SendDtmf("5"));
+ trilist.SetSigFalseAction(joinMap.Dtmf6.JoinNumber, () => SendDtmf("6"));
+ trilist.SetSigFalseAction(joinMap.Dtmf7.JoinNumber, () => SendDtmf("7"));
+ trilist.SetSigFalseAction(joinMap.Dtmf8.JoinNumber, () => SendDtmf("8"));
+ trilist.SetSigFalseAction(joinMap.Dtmf9.JoinNumber, () => SendDtmf("9"));
+ trilist.SetSigFalseAction(joinMap.DtmfStar.JoinNumber, () => SendDtmf("*"));
+ trilist.SetSigFalseAction(joinMap.DtmfPound.JoinNumber, () => SendDtmf("#"));
+ }
+
+ private void LinkVideoCodecCameraLayoutsToApi(IHasCodecLayouts codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.CameraLayout.JoinNumber, codec.LocalLayoutToggle);
+
+ codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CameraLayoutStringFb.JoinNumber]);
+ }
+
+ private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn);
+ trilist.SetSigFalseAction(joinMap.CameraModeManual.JoinNumber, codec.CameraAutoModeOff);
+
+ codec.CameraAutoModeIsOnFeedback.OutputChange += (o, a) =>
+ {
+ var offCodec = codec as IHasCameraOff;
+
+ if (offCodec != null)
+ {
+ if (offCodec.CameraIsOffFeedback.BoolValue)
+ {
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+ };
+
+ var offModeCodec = codec as IHasCameraOff;
+
+ if (offModeCodec != null)
+ {
+ if (offModeCodec.CameraIsOffFeedback.BoolValue)
+ {
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+ }
+
+ private void LinkVideoCodecSelfviewToApi(IHasCodecSelfView codec, BasicTriList trilist,
+ VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.CameraSelfView.JoinNumber, codec.SelfViewModeToggle);
+
+ codec.SelfviewIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CameraSelfView.JoinNumber]);
+ }
+
+ private void LinkVideoCodecCameraToApi(IHasCodecCameras codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ //Camera PTZ
+ trilist.SetBoolSigAction(joinMap.CameraTiltUp.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.TiltUp();
+ else camera.TiltStop();
+ });
+
+ trilist.SetBoolSigAction(joinMap.CameraTiltDown.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.TiltDown();
+ else camera.TiltStop();
+ });
+ trilist.SetBoolSigAction(joinMap.CameraPanLeft.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.PanLeft();
+ else camera.PanStop();
+ });
+ trilist.SetBoolSigAction(joinMap.CameraPanRight.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.PanRight();
+ else camera.PanStop();
+ });
+
+ trilist.SetBoolSigAction(joinMap.CameraZoomIn.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.ZoomIn();
+ else camera.ZoomStop();
+ });
+
+ trilist.SetBoolSigAction(joinMap.CameraZoomOut.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.ZoomOut();
+ else camera.ZoomStop();
+ });
+
+ //Camera Select
+ trilist.SetUShortSigAction(joinMap.CameraNumberSelect.JoinNumber, (i) =>
+ {
+ if (codec.SelectedCamera == null) return;
+
+ codec.SelectCamera(codec.Cameras[i].Key);
+ });
+
+ codec.CameraSelected += (sender, args) =>
+ {
+ var i = (ushort)codec.Cameras.FindIndex((c) => c.Key == args.SelectedCamera.Key);
+
+ if (codec is IHasCodecRoomPresets)
+ {
+ return;
+ }
+
+ if (!(args.SelectedCamera is IHasCameraPresets))
+ {
+ return;
+ }
+
+ var cam = args.SelectedCamera as IHasCameraPresets;
+ SetCameraPresetNames(cam.Presets);
+
+ (args.SelectedCamera as IHasCameraPresets).PresetsListHasChanged += (o, eventArgs) => SetCameraPresetNames(cam.Presets);
+
+ trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber,
+ (a) =>
+ {
+ cam.PresetSelect(a);
+ trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, a);
+ });
+
+ trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber,
+ () =>
+ {
+ cam.PresetStore(trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue,
+ String.Empty);
+ trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000);
+ });
+ };
+
+ if (!(codec is IHasCodecRoomPresets)) return;
+
+ var presetCodec = codec as IHasCodecRoomPresets;
+
+ presetCodec.CodecRoomPresetsListHasChanged +=
+ (sender, args) => SetCameraPresetNames(presetCodec.NearEndPresets);
+
+ //Camera Presets
+ trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, (i) =>
+ {
+ presetCodec.CodecRoomPresetSelect(i);
+
+ trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, i);
+ });
+
+ trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber,
+ () =>
+ {
+ presetCodec.CodecRoomPresetStore(
+ trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, String.Empty);
+ trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000);
+ });
+ }
+
+ private string SetCameraPresetNames(IEnumerable presets)
+ {
+ return SetCameraPresetNames(presets.Select(p => p.Description).ToList());
+ }
+
+ private string SetCameraPresetNames(IEnumerable presets)
+ {
+ return SetCameraPresetNames(presets.Select(p => p.Description).ToList());
+ }
+
+ private string SetCameraPresetNames(ICollection presets)
+ {
+ var i = 1; //start index for xsig;
+
+ var tokenArray = new XSigToken[presets.Count];
+
+ foreach (var preset in presets)
+ {
+ var cameraPreset = new XSigSerialToken(i, preset);
+ tokenArray[i - 1] = cameraPreset;
+ i++;
+ }
+
+ return GetXSigString(tokenArray);
+ }
+
+ private string GetXSigString(XSigToken[] tokenArray)
+ {
+ string returnString;
+ using (var s = new MemoryStream())
+ {
+ using (var tw = new XSigTokenStreamWriter(s, true))
+ {
+ tw.WriteXSigData(tokenArray);
+ }
+
+ var xSig = s.ToArray();
+
+ returnString = Encoding.GetEncoding(XSigEncoding).GetString(xSig, 0, xSig.Length);
+ }
+
+ return returnString;
+ }
+
+ #endregion
+ }
+
+
+ ///
+ /// Used to track the status of syncronizing the phonebook values when connecting to a codec or refreshing the phonebook info
+ ///
+ public class CodecPhonebookSyncState : IKeyed
+ {
+ private bool _InitialSyncComplete;
+
+ public CodecPhonebookSyncState(string key)
+ {
+ Key = key;
+
+ CodecDisconnected();
+ }
+
+ public bool InitialSyncComplete
+ {
+ get { return _InitialSyncComplete; }
+ private set
+ {
+ if (value == true)
+ {
+ var handler = InitialSyncCompleted;
+ if (handler != null)
+ {
+ handler(this, new EventArgs());
+ }
+ }
+ _InitialSyncComplete = value;
+ }
+ }
+
+ public bool InitialPhonebookFoldersWasReceived { get; private set; }
+
+ public bool NumberOfContactsWasReceived { get; private set; }
+
+ public bool PhonebookRootEntriesWasRecieved { get; private set; }
+
+ public bool PhonebookHasFolders { get; private set; }
+
+ public int NumberOfContacts { get; private set; }
+
+ #region IKeyed Members
+
+ public string Key { get; private set; }
+
+ #endregion
+
+ public event EventHandler InitialSyncCompleted;
+
+ public void InitialPhonebookFoldersReceived()
+ {
+ InitialPhonebookFoldersWasReceived = true;
+
+ CheckSyncStatus();
+ }
+
+ public void PhonebookRootEntriesReceived()
+ {
+ PhonebookRootEntriesWasRecieved = true;
+
+ CheckSyncStatus();
+ }
+
+ public void SetPhonebookHasFolders(bool value)
+ {
+ PhonebookHasFolders = value;
+
+ Debug.Console(1, this, "Phonebook has folders: {0}", PhonebookHasFolders);
+ }
+
+ public void SetNumberOfContacts(int contacts)
+ {
+ NumberOfContacts = contacts;
+ NumberOfContactsWasReceived = true;
+
+ Debug.Console(1, this, "Phonebook contains {0} contacts.", NumberOfContacts);
+
+ CheckSyncStatus();
+ }
+
+ public void CodecDisconnected()
+ {
+ InitialPhonebookFoldersWasReceived = false;
+ PhonebookHasFolders = false;
+ NumberOfContacts = 0;
+ NumberOfContactsWasReceived = false;
+ }
+
+ private void CheckSyncStatus()
+ {
+ if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved)
+ {
+ InitialSyncComplete = true;
+ Debug.Console(1, this, "Initial Phonebook Sync Complete!");
+ }
+ else
+ {
+ InitialSyncComplete = false;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
index 4f4eddbc..36cce89f 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
@@ -1,1335 +1,1335 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-using Crestron.SimplSharp;
-
-using PepperDash.Core;
-using PepperDash.Essentials.Devices.Common.Codec;
-
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
-
-namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
-{
- public enum eZoomRoomResponseType
- {
- zEvent,
- zStatus,
- zConfiguration,
- zCommand
- }
-
- public abstract class NotifiableObject : INotifyPropertyChanged
- {
- #region INotifyPropertyChanged Members
-
- public event PropertyChangedEventHandler PropertyChanged;
-
- protected void NotifyPropertyChanged(string propertyName)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
- }
- }
-
- #endregion
- }
-
- ///
- /// Used to track the current status of a ZoomRoom
- ///
- public class ZoomRoomStatus
- {
- public zStatus.Login Login { get; set; }
- public zStatus.SystemUnit SystemUnit { get; set; }
- public zStatus.Phonebook Phonebook { get; set; }
- public zStatus.Call Call { get; set; }
- public zStatus.Capabilities Capabilities { get; set; }
- public zStatus.Sharing Sharing { get; set; }
- public zStatus.NumberOfScreens NumberOfScreens { get; set; }
- public zStatus.Layout Layout { get; set; }
- public zStatus.Video Video { get; set; }
- public zStatus.CameraShare CameraShare { get; set; }
- public List AudioInputs { get; set; }
- public List AudioOuputs { get; set; }
- public List Cameras { get; set; }
- public zEvent.PhoneCallStatus PhoneCall { get; set; }
-
- public ZoomRoomStatus()
- {
- Login = new zStatus.Login();
- SystemUnit = new zStatus.SystemUnit();
- Phonebook = new zStatus.Phonebook();
- Call = new zStatus.Call();
- Capabilities = new zStatus.Capabilities();
- Sharing = new zStatus.Sharing();
- NumberOfScreens = new zStatus.NumberOfScreens();
- Layout = new zStatus.Layout();
- Video = new zStatus.Video();
- CameraShare = new zStatus.CameraShare();
- AudioInputs = new List();
- AudioOuputs = new List();
- Cameras = new List();
- PhoneCall = new zEvent.PhoneCallStatus();
- }
- }
-
- ///
- /// Used to track the current configuration of a ZoomRoom
- ///
- public class ZoomRoomConfiguration
- {
- public zConfiguration.Call Call { get; set; }
- public zConfiguration.Audio Audio { get; set; }
- public zConfiguration.Video Video { get; set; }
- public zConfiguration.Client Client { get; set; }
- public zConfiguration.Camera Camera { get; set; }
-
- public ZoomRoomConfiguration()
- {
- Call = new zConfiguration.Call();
- Audio = new zConfiguration.Audio();
- Video = new zConfiguration.Video();
- Client = new zConfiguration.Client();
- Camera = new zConfiguration.Camera();
- }
- }
-
- ///
- /// Represents a response from a ZoomRoom system
- ///
- public class Response
- {
- public Status Status { get; set; }
- public bool Sync { get; set; }
- [JsonProperty("topKey")]
- public string TopKey { get; set; }
- [JsonProperty("type")]
- public string Type { get; set; }
-
- public Response()
- {
- Status = new Status();
- }
- }
-
- public class Status
- {
- [JsonProperty("message")]
- public string Message { get; set; }
- [JsonProperty("state")]
- public string State { get; set; }
- }
-
-
- ///
- /// zStatus class stucture
- ///
- public class zStatus
- {
- public class Login
- {
- [JsonProperty("ZAAPI Release")]
- public string ZAAPIRelease { get; set; }
- [JsonProperty("Zoom Room Release")]
- public string ZoomRoomRelease { get; set; }
- }
-
- public class SystemUnit
- {
- [JsonProperty("email")]
- public string Email { get; set; }
- [JsonProperty("login_type")]
- public string LoginType { get; set; }
- [JsonProperty("meeting_number")]
- public string MeetingNumber { get; set; }
- [JsonProperty("platform")]
- public string Platform { get; set; }
- [JsonProperty("room_info")]
- public RoomInfo RoomInfo { get; set; }
- [JsonProperty("room_version")]
- public string RoomVersion { get; set; }
-
- public SystemUnit()
- {
- RoomInfo = new RoomInfo();
- }
- }
-
- public class RoomInfo
- {
- [JsonProperty("account_email")]
- public string AccountEmail { get; set; }
- [JsonProperty("display_version")]
- public string DisplayVersion { get; set; }
- [JsonProperty("is_auto_answer_enabled")]
- public bool AutoAnswerIsEnabled { get; set; }
- [JsonProperty("is_auto_answer_selected")]
- public bool AutoAnswerIsSelected { get; set; }
- [JsonProperty("room_name")]
- public string RoomName { get; set; }
- }
-
- public class CloudPbxInfo
- {
- [JsonProperty("company_number")]
- public string CompanyNumber { get; set; }
- [JsonProperty("extension")]
- public string Extension { get; set; }
- [JsonProperty("isValid")]
- public bool IsValid { get; set; }
- }
-
- public enum ePresence
- {
- PRESENCE_OFFLINE,
- PRESENCE_ONLINE,
- PRESENCE_AWAY,
- PRESENCE_BUSY,
- PRESENCE_DND
- }
-
- public class Contact
- {
- [JsonProperty("avatarURL")]
- public string AvatarURL { get; set; }
- [JsonProperty("cloud_pbx_info")]
- public CloudPbxInfo CloudPbxInfo { get; set; }
- [JsonProperty("email")]
- public string Email { get; set; }
- [JsonProperty("firstName")]
- public string FirstName { get; set; }
- [JsonProperty("index")]
- public int Index { get; set; }
- [JsonProperty("isLegacy")]
- public bool IsLegacy { get; set; }
- [JsonProperty("isZoomRoom")]
- public bool IsZoomRoom { get; set; }
- [JsonProperty("jid")]
- public string Jid { get; set; }
- [JsonProperty("lastName")]
- public string LastName { get; set; }
- [JsonProperty("onDesktop")]
- public bool OnDesktop { get; set; }
- [JsonProperty("onMobile")]
- public bool OnMobile { get; set; }
- [JsonProperty("phoneNumber")]
- public string PhoneNumber { get; set; }
- [JsonProperty("presence")]
- public ePresence Presence { get; set; }
- [JsonProperty("presence_status")]
- public int PresenceStatus { get; set; }
- [JsonProperty("screenName")]
- public string ScreenName { get; set; }
- [JsonProperty("sip_phone_number")]
- public string SipPhoneNumber { get; set; }
-
-
- public Contact()
- {
- CloudPbxInfo = new CloudPbxInfo();
- }
- }
-
- ///
- /// Used to be able to inplement IInvitableContact on DirectoryContact
- ///
- public class ZoomDirectoryContact : DirectoryContact, IInvitableContact
- {
-
- }
-
- public class Phonebook
- {
- [JsonProperty("Contacts")]
- public List Contacts { get; set; }
-
- public Phonebook()
- {
- Contacts = new List();
- }
-
- ///
- /// Converts from zStatus.Contact types to generic directory items
- ///
- ///
- public static CodecDirectory ConvertZoomContactsToGeneric(List zoomContacts)
- {
- var directory = new CodecDirectory();
-
- var folders = new List();
-
- var roomFolder = new DirectoryFolder();
-
- var contactFolder = new DirectoryFolder();
-
- var contacts = new List();
-
- // Check if there are any zoom rooms
- var zoomRooms = zoomContacts.FindAll(c => c.IsZoomRoom);
-
- if (zoomRooms.Count > 0)
- {
- // If so, setup a rooms and contacts folder and add them.
- roomFolder.Name = "Rooms";
- roomFolder.ParentFolderId = "root";
- roomFolder.FolderId = "rooms";
-
- contactFolder.Name = "Contacts";
- contactFolder.ParentFolderId = "root";
- contactFolder.FolderId = "contacts";
-
- folders.Add(roomFolder);
- folders.Add(contactFolder);
-
- directory.AddFoldersToDirectory(folders);
- }
-
- try
- {
- if (zoomContacts.Count == 0) return directory;
- {
- foreach (Contact c in zoomContacts)
- {
- var contact = new ZoomDirectoryContact {Name = c.ScreenName, ContactId = c.Jid};
-
- if (folders.Count > 0)
- {
- contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts";
- }
-
- contacts.Add(contact);
- }
-
- directory.AddContactsToDirectory(contacts);
- }
- }
- catch (Exception e)
- {
- Debug.Console(1, "Error converting Zoom Phonebook results to generic: {0}", e);
- }
-
- return directory;
- }
- }
-
- public enum eCallStatus
- {
- UNKNOWN,
- NOT_IN_MEETING,
- CONNECTING_MEETING,
- IN_MEETING,
- LOGGED_OUT
- }
-
- public class ClosedCaption
- {
- public bool Available { get; set; }
- }
-
- public class Call : NotifiableObject
- {
- private eCallStatus _status;
- private List _participants;
-
- public bool IsInCall;
-
- public eCallStatus Status
- {
- get
- {
- return _status;
- }
- set
- {
- if (value != _status)
- {
- _status = value;
- IsInCall = _status == eCallStatus.IN_MEETING || _status == eCallStatus.CONNECTING_MEETING;
- NotifyPropertyChanged("Status");
- }
- }
- }
- public ClosedCaption ClosedCaption { get; set; }
- public List Participants
- {
- get
- {
- return _participants;
- }
- set
- {
- _participants = value;
- NotifyPropertyChanged("Participants");
- }
- }
- public zEvent.SharingState Sharing { get; set; }
-
- public CallRecordInfo CallRecordInfo { get; set; }
-
- private zCommand.InfoResult _info;
-
- public zCommand.InfoResult Info
- {
- get
- {
- return _info;
- }
- set
- {
- _info = value;
- NotifyPropertyChanged("Info");
- }
- }
-
- public Call()
- {
- ClosedCaption = new ClosedCaption();
- Participants = new List();
- Sharing = new zEvent.SharingState();
- CallRecordInfo = new CallRecordInfo();
- Info = new zCommand.InfoResult();
- }
- }
-
- public class Capabilities
- {
- public bool aec_Setting_Stored_In_ZR { get; set; }
- public bool can_Dtmf_For_Invite_By_Phone { get; set; }
- public bool can_Mute_On_Entry { get; set; }
- public bool can_Ringing_In_Pstn_Call { get; set; }
- public bool can_Switch_To_Specific_Camera { get; set; }
- public bool is_Airhost_Disabled { get; set; }
- public bool pstn_Call_In_Local_resentation { get; set; }
- public bool support_Claim_Host { get; set; }
- public bool support_Out_Room_Display { get; set; }
- public bool support_Pin_And_Spotlight { get; set; }
- public bool supports_Audio_Checkup { get; set; }
- public bool supports_CheckIn { get; set; }
- public bool supports_Cloud_PBX { get; set; }
- public bool supports_Encrypted_Connection { get; set; }
- public bool supports_Expel_User_Permanently { get; set; }
- public bool supports_H323_DTMF { get; set; }
- public bool supports_Hdmi_Cec_Control { get; set; }
- public bool supports_Highly_Reverberant_Room { get; set; }
- public bool supports_Loading_Contacts_Dynamically { get; set; }
- public bool supports_Loading_Participants_Dynamically { get; set; }
- public bool supports_Mic_Record_Test { get; set; }
- public bool supports_Multi_Share { get; set; }
- public bool supports_ShareCamera { get; set; }
- public bool supports_Share_For_Floating_And_Content_Only { get; set; }
- public bool supports_Sip_Call_out { get; set; }
- public bool supports_Software_Audio_Processing { get; set; }
- public bool supports_Web_Settings_Push { get; set; }
- }
-
- public class Sharing : NotifiableObject
- {
- private string _dispState;
- private string _password;
-
- public string directPresentationPairingCode { get; set; }
- ///
- /// Laptop client sharing key
- ///
- public string directPresentationSharingKey { get; set; }
- public string dispState
- {
- get
- {
- return _dispState;
- }
- set
- {
- if (value != _dispState)
- {
- _dispState = value;
- NotifyPropertyChanged("dispState");
- }
- }
- }
- public bool isAirHostClientConnected { get; set; }
- public bool isBlackMagicConnected { get; set; }
- public bool isBlackMagicDataAvailable { get; set; }
- public bool isDirectPresentationConnected { get; set; }
- public bool isSharingBlackMagic { get; set; }
- ///
- /// IOS Airplay code
- ///
- public string password
- {
- get
- {
- return _password;
- }
- set
- {
- if (value != _password)
- {
- _password = value;
- NotifyPropertyChanged("password");
- }
- }
- }
- public string serverName { get; set; }
- public string wifiName { get; set; }
- }
-
- public class NumberOfScreens
- {
- [JsonProperty("NumberOfCECScreens")]
- public int NumOfCECScreens { get; set; }
- [JsonProperty("NumberOfScreens")]
- public int NumOfScreens { get; set; }
- }
-
- ///
- /// AudioInputLine/AudioOutputLine/VideoCameraLine list item
- ///
- public class AudioVideoInputOutputLineItem
- {
- public string Alias { get; set; }
- public string Name { get; set; }
- public bool Selected { get; set; }
- public bool combinedDevice { get; set; }
- public string id { get; set; }
- public bool manuallySelected { get; set; }
- public int numberOfCombinedDevices { get; set; }
- public int ptzComId { get; set; }
- }
-
- public class Video
- {
- public bool Optimizable { get; set; }
- }
-
- public class CameraShare : NotifiableObject
- {
- private bool _canControlCamera;
- private bool _isSharing;
-
- [JsonProperty("can_Control_Camera")]
- public bool CanControlCamera
- {
- get
- {
- return _canControlCamera;
- }
- set
- {
- if (value != _canControlCamera)
- {
- _canControlCamera = value;
- NotifyPropertyChanged("CanControlCamera");
- }
- }
- }
- public string id { get; set; }
- public bool is_Mirrored { get; set; }
- [JsonProperty("is_Sharing")]
- public bool IsSharing
- {
- get
- {
- return _isSharing;
- }
- set
- {
- if (value != _isSharing)
- {
- _isSharing = value;
- NotifyPropertyChanged("IsSharing");
- }
- }
- }
- public int pan_Tilt_Speed { get; set; }
-
- }
-
- public class Layout
- {
- public bool can_Adjust_Floating_Video { get; set; }
- public bool can_Switch_Floating_Share_Content { get; set; }
- public bool can_Switch_Share_On_All_Screens { get; set; }
- public bool can_Switch_Speaker_View { get; set; }
- public bool can_Switch_Wall_View { get; set; }
- public bool is_In_First_Page { get; set; }
- public bool is_In_Last_Page { get; set; }
- public bool is_supported { get; set; }
- public int video_Count_In_Current_Page { get; set; }
- public string video_type { get; set; }
- }
-
- public class CallRecordInfo
- {
- public bool canRecord { get; set; }
- public bool emailRequired { get; set; }
- public bool amIRecording { get; set; }
- public bool meetingIsBeingRecorded { get; set; }
- }
- }
-
- ///
- /// zEvent Class Structure
- ///
- public class zEvent
- {
- public class NeedWaitForHost
- {
- public bool Wait { get; set; }
- }
-
- public class IncomingCallIndication
- {
- public string callerJID { get; set; }
- public string calleeJID { get; set; }
- public string meetingID { get; set; }
- public string password { get; set; }
- public string meetingOption { get; set; }
- public long MeetingNumber { get; set; }
- public string callerName { get; set; }
- public string avatarURL { get; set; }
- public int lifeTime { get; set; }
- public bool accepted { get; set; }
- }
-
- public class CallConnectError
- {
- public int error_code { get; set; }
- public string error_message { get; set; }
- }
-
- public class CallDisconnect
- {
- public bool Successful
- {
- get
- {
- return success == "on";
- }
- }
-
- public string success { get; set; }
- }
-
- public class Layout
- {
- public bool Sharethumb { get; set; }
- }
-
- public class Call
- {
- public Layout Layout { get; set; }
- }
-
- public class Client
- {
- public Call Call { get; set; }
- }
-
- public enum eSharingState
- {
- None,
- Connecting,
- Sending,
- Receiving,
- Send_Receiving
- }
-
- public class SharingState : NotifiableObject
- {
- private bool _paused;
- private eSharingState _state;
-
- public bool IsSharing;
-
- [JsonProperty("paused")]
- public bool Paused
- {
- get
- {
- return _paused;
- }
- set
- {
- if (value != _paused)
- {
- _paused = value;
- NotifyPropertyChanged("Paused");
- }
- }
- }
- [JsonProperty("state")]
- public eSharingState State
- {
- get
- {
- return _state;
- }
- set
- {
- if (value != _state)
- {
- _state = value;
- IsSharing = _state == eSharingState.Sending;
- NotifyPropertyChanged("State");
- }
- }
- }
- }
-
- public class PinStatusOfScreenNotification
- {
- [JsonProperty("can_be_pinned")]
- public bool CanBePinned { get; set; }
- [JsonProperty("can_pin_share")]
- public bool CanPinShare { get; set; }
- [JsonProperty("pinned_share_source_id")]
- public int PinnedShareSourceId { get; set; }
- [JsonProperty("pinned_user_id")]
- public int PinnedUserId { get; set; }
- [JsonProperty("screen_index")]
- public int ScreenIndex { get; set; }
- [JsonProperty("screen_layout")]
- public int ScreenLayout { get; set; }
- [JsonProperty("share_source_type")]
- public int ShareSourceType { get; set; }
- [JsonProperty("why_cannot_pin_share")]
- public string WhyCannotPinShare { get; set; }
- }
-
- public class PhoneCallStatus:NotifiableObject
- {
- private bool _isIncomingCall;
- private string _peerDisplayName;
- private string _peerNumber;
-
- private bool _offHook;
-
- public string CallId { get; set; }
- public bool IsIncomingCall {
- get { return _isIncomingCall; }
- set
- {
- if(value == _isIncomingCall) return;
-
- _isIncomingCall = value;
- NotifyPropertyChanged("IsIncomingCall");
- } }
-
- public string PeerDisplayName
- {
- get { return _peerDisplayName; }
- set
- {
- if (value == _peerDisplayName) return;
- _peerDisplayName = value;
- NotifyPropertyChanged("PeerDisplayName");
- }
- }
-
- public string PeerNumber
- {
- get { return _peerNumber; }
- set
- {
- if (value == _peerNumber) return;
-
- _peerNumber = value;
- NotifyPropertyChanged("PeerNumber");
- }
- }
-
- public string PeerUri { get; set; }
-
- private ePhoneCallStatus _status;
- public ePhoneCallStatus Status
- {
- get { return _status; }
- set
- {
- _status = value;
- OffHook = _status == ePhoneCallStatus.PhoneCallStatus_Accepted ||
- _status == ePhoneCallStatus.PhoneCallStatus_InCall ||
- _status == ePhoneCallStatus.PhoneCallStatus_Init ||
- _status == ePhoneCallStatus.PhoneCallStatus_Ringing;
- }
- }
-
- public bool OffHook
- {
- get { return _offHook; }
- set
- {
- if (value == _offHook) return;
-
- _offHook = value;
- NotifyPropertyChanged("OffHook");
- }
- }
- }
-
- public enum ePhoneCallStatus
- {
- PhoneCallStatus_Ringing,
- PhoneCallStatus_Terminated,
- PhoneCallStatus_Accepted,
- PhoneCallStatus_InCall,
- PhoneCallStatus_Init,
- }
- }
-
- ///
- /// zConfiguration class structure
- ///
- public class zConfiguration
- {
- public class Sharing
- {
- [JsonProperty("optimize_video_sharing")]
- public bool OptimizeVideoSharing { get; set; }
- }
-
- public class Camera : NotifiableObject
- {
- private bool _mute;
-
- public bool Mute
- {
- get { return _mute; }
- set
- {
- Debug.Console(1, "Camera Mute response received: {0}", value);
-
- if (value == _mute) return;
-
- _mute = value;
- NotifyPropertyChanged("Mute");
- }
- }
- }
-
- public class Microphone : NotifiableObject
- {
- private bool _mute;
-
- public bool Mute
- {
- get
- {
- return _mute;
- }
- set
- {
- if(value != _mute)
- {
- _mute = value;
- NotifyPropertyChanged("Mute");
- }
- }
- }
- }
-
- public enum eLayoutStyle
- {
- Gallery,
- Speaker,
- Strip,
- ShareAll
- }
-
- public enum eLayoutSize
- {
- Off,
- Size1,
- Size2,
- Size3,
- Strip
- }
-
- public enum eLayoutPosition
- {
- Center,
- Up,
- Right,
- UpRight,
- Down,
- DownRight,
- Left,
- UpLeft,
- DownLeft
- }
-
- public class Layout:NotifiableObject
- {
- public bool ShareThumb { get; set; }
- public eLayoutStyle Style { get; set; }
- public eLayoutSize Size { get; set; }
-
- private eLayoutPosition _position;
- public eLayoutPosition Position {
- get { return _position; }
- set
- {
- _position = value;
- NotifyPropertyChanged("Position");
- } }
- }
-
- public class Lock
- {
- public bool Enable { get; set; }
- }
-
- public class ClosedCaption
- {
- public bool Visible { get; set; }
- public int FontSize { get; set; }
- }
-
- public class MuteUserOnEntry
- {
- public bool Enable { get; set; }
- }
-
- public class Call
- {
- public Sharing Sharing { get; set; }
- public Camera Camera { get; set; }
- public Microphone Microphone { get; set; }
- public Layout Layout { get; set; }
- public Lock Lock { get; set; }
- public MuteUserOnEntry MuteUserOnEntry { get; set; }
- public ClosedCaption ClosedCaption { get; set; }
-
-
- public Call()
- {
- Sharing = new Sharing();
- Camera = new Camera();
- Microphone = new Microphone();
- Layout = new Layout();
- Lock = new Lock();
- MuteUserOnEntry = new MuteUserOnEntry();
- ClosedCaption = new ClosedCaption();
- }
- }
-
- public class Audio
- {
- public Input Input { get; set; }
- public Output Output { get; set; }
-
- public Audio()
- {
- Input = new Input();
- Output = new Output();
- }
- }
-
- public class Input : Output
- {
- [JsonProperty("reduce_reverb")]
- public bool ReduceReverb { get; set; }
- }
-
- public class Output : NotifiableObject
- {
- private int _volume;
-
- [JsonProperty("volume")]
- public int Volume
- {
- get
- {
- return _volume;
- }
- set
- {
- if (value != _volume)
- {
- _volume = value;
- NotifyPropertyChanged("Volume");
- }
- }
- }
- [JsonProperty("selectedId")]
- public string SelectedId { get; set; }
- [JsonProperty("is_sap_disabled")]
- public bool IsSapDisabled { get; set; }
- }
-
- public class Video : NotifiableObject
- {
- private bool _hideConfSelfVideo;
-
- [JsonProperty("hide_conf_self_video")]
- public bool HideConfSelfVideo
- {
- get
- {
- return _hideConfSelfVideo;
- }
- set
- {
- if (value != _hideConfSelfVideo)
- {
- _hideConfSelfVideo = value;
- NotifyPropertyChanged("HideConfSelfVideo");
- }
- }
- }
-
- public VideoCamera Camera { get; set; }
-
- public Video()
- {
- Camera = new VideoCamera();
- }
- }
-
- public class VideoCamera : NotifiableObject
- {
- private string _selectedId;
-
- [JsonProperty("selectedId")]
- public string SelectedId {
- get
- {
- return _selectedId;
- }
- set
- {
- if (value != _selectedId)
- {
- _selectedId = value;
- NotifyPropertyChanged("SelectedId");
- }
- }
-
- }
- public bool Mirror { get; set; }
- }
-
- public class Client
- {
- public string appVersion { get; set; }
- public string deviceSystem { get; set; }
- }
-
- }
-
- ///
- /// zCommand class structure
- ///
- public class zCommand
- {
- public class BookingsListResult
- {
- [JsonProperty("accessRole")]
- public string AccessRole { get; set; }
- [JsonProperty("calendarChangeKey")]
- public string CalendarChangeKey { get; set; }
- [JsonProperty("calendarID")]
- public string CalendarId { get; set; }
- [JsonProperty("checkIn")]
- public bool CheckIn { get; set; }
- [JsonProperty("creatorEmail")]
- public string CreatorEmail { get; set; }
- [JsonProperty("creatorName")]
- public string CreatorName { get; set; }
- [JsonProperty("endTime")]
- public DateTime EndTime { get; set; }
- [JsonProperty("hostName")]
- public string HostName { get; set; }
- [JsonProperty("isInstantMeeting")]
- public bool IsInstantMeeting { get; set; }
- [JsonProperty("isPrivate")]
- public bool IsPrivate { get; set; }
- [JsonProperty("location")]
- public string Location { get; set; }
- [JsonProperty("meetingName")]
- public string MeetingName { get; set; }
- [JsonProperty("meetingNumber")]
- public string MeetingNumber { get; set; }
- [JsonProperty("scheduledFrom")]
- public string ScheduledFrom { get; set; }
- [JsonProperty("startTime")]
- public DateTime StartTime { get; set; }
- [JsonProperty("third_party")]
- public ThirdParty ThirdParty { get; set; }
- }
-
- public static List GetGenericMeetingsFromBookingResult(List bookings,
- int minutesBeforeMeetingStart)
- {
- var rv = GetGenericMeetingsFromBookingResult(bookings);
-
- foreach (var meeting in rv)
- {
- meeting.MinutesBeforeMeeting = minutesBeforeMeetingStart;
- }
-
- return rv;
- }
- ///
- /// Extracts the necessary meeting values from the Zoom bookings response and converts them to the generic class
- ///
- ///
- ///
- public static List GetGenericMeetingsFromBookingResult(List bookings)
- {
- var meetings = new List();
-
- if (Debug.Level > 0)
- {
- Debug.Console(1, "Meetings List:\n");
- }
-
- foreach (var b in bookings)
- {
- var meeting = new Meeting();
-
- if (b.MeetingNumber != null)
- meeting.Id = b.MeetingNumber;
- if (b.CreatorName != null)
- meeting.Organizer = b.CreatorName;
- if (b.MeetingName != null)
- meeting.Title = b.MeetingName;
- //if (b.Agenda != null)
- // meeting.Agenda = b.Agenda.Value;
- if (b.StartTime != null)
- meeting.StartTime = b.StartTime;
- if (b.EndTime != null)
- meeting.EndTime = b.EndTime;
-
- meeting.Privacy = b.IsPrivate ? eMeetingPrivacy.Private : eMeetingPrivacy.Public;
-
- // No meeting.Calls data exists for Zoom Rooms. Leaving out for now.
- var now = DateTime.Now;
- if (meeting.StartTime < now && meeting.EndTime < now)
- {
- Debug.Console(1, "Skipping meeting {0}. Meeting is in the past.", meeting.Title);
- continue;
- }
-
- meetings.Add(meeting);
-
- if (Debug.Level > 0)
- {
- Debug.Console(1, "Title: {0}, ID: {1}, Organizer: {2}", meeting.Title, meeting.Id, meeting.Organizer);
- Debug.Console(1, " Start Time: {0}, End Time: {1}, Duration: {2}", meeting.StartTime, meeting.EndTime, meeting.Duration);
- Debug.Console(1, " Joinable: {0}\n", meeting.Joinable);
- }
- }
-
- meetings.OrderBy(m => m.StartTime);
-
- return meetings;
- }
-
- public class HandStatus
- {
- [JsonProperty("is_raise_hand")]
- public bool IsRaiseHand { get; set; }
- [JsonProperty("optimize_vis_validideo_sharing")]
- public string IsValid { get; set; }
- [JsonProperty("time_stamp")]
- public string TimeStamp { get; set; }
- }
-
- public class ListParticipant
- {
- [JsonProperty("audio_status state")]
- public string AudioStatusState { get; set; }
- [JsonProperty("audio_status type")]
- public string AudioStatusType { get; set; }
- [JsonProperty("avatar_url")]
- public string AvatarUrl { get; set; }
- [JsonProperty("camera_status am_i_controlling")]
- public bool CameraStatusAmIControlling { get; set; }
- [JsonProperty("camera_status can_i_request_control")]
- public bool CameraStatusCanIRequestConrol { get; set; }
- [JsonProperty("camera_status can_move_camera")]
- public bool CameraStatusCanMoveCamera { get; set; }
- [JsonProperty("camera_status can_switch_camera")]
- public bool CameraStatusCanSwitchCamera { get; set; }
- [JsonProperty("camera_status can_zoom_camera")]
- public bool CameraStatusCanZoomCamera { get; set; }
- [JsonProperty("can_edit_closed_caption")]
- public bool CanEditClosedCaption { get; set; }
- [JsonProperty("can_record")]
- public bool CanRecord { get; set; }
- [JsonProperty("event")]
- public string Event { get; set; }
- [JsonProperty("hand_status")]
- public HandStatus HandStatus { get; set; }
- [JsonProperty("isCohost")]
- public bool IsCohost { get; set; }
- [JsonProperty("is_client_support_closed_caption")]
- public bool IsClientSupportClosedCaption { get; set; }
- [JsonProperty("is_client_support_coHost")]
- public bool IsClientSupportCoHost { get; set; }
- [JsonProperty("is_host")]
- public bool IsHost { get; set; }
- [JsonProperty("is_myself")]
- public bool IsMyself { get; set; }
- [JsonProperty("is_recording")]
- public bool IsRecording { get; set; }
- [JsonProperty("is_video_can_mute_byHost")]
- public bool IsVideoCanMuteByHost { get; set; }
- [JsonProperty("is_video_can_unmute_byHost")]
- public bool IsVideoCanUnmuteByHost { get; set; }
- [JsonProperty("local_recording_disabled")]
- public bool LocalRecordingDisabled { get; set; }
- [JsonProperty("user_id")]
- public int UserId { get; set; }
- [JsonProperty("user_name")]
- public string UserName { get; set; }
- [JsonProperty("user_type")]
- public string UserType { get; set; }
- [JsonProperty("video_status has_source")]
- public bool VideoStatusHasSource { get; set; }
- [JsonProperty("video_status is_receiving")]
- public bool VideoStatusIsReceiving { get; set; }
- [JsonProperty("video_status is_sending")]
- public bool VideoStatusIsSending { get; set; }
-
- public ListParticipant()
- {
- HandStatus = new HandStatus();
- }
-
- public static List GetGenericParticipantListFromParticipantsResult(
- List participants)
- {
- return
- participants.Select(
- p =>
- new Participant
- {
- Name = p.UserName,
- IsHost = p.IsHost,
- CanMuteVideo = p.IsVideoCanMuteByHost,
- CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
- AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
- VideoMuteFb = p.VideoStatusIsSending
- }).ToList();
- }
- }
-
- public class CallinCountryList
- {
- public int code { get; set; }
- public string display_number { get; set; }
- public string id { get; set; }
- public string name { get; set; }
- public string number { get; set; }
- }
-
- public class CalloutCountryList
- {
- public int code { get; set; }
- public string display_number { get; set; }
- public string id { get; set; }
- public string name { get; set; }
- public string number { get; set; }
- }
-
- public class TollFreeCallinList
- {
- public int code { get; set; }
- public string display_number { get; set; }
- public string id { get; set; }
- public string name { get; set; }
- public string number { get; set; }
- }
-
- public class Info
- {
- public List callin_country_list { get; set; }
- public List callout_country_list { get; set; }
- public List toll_free_callin_list { get; set; }
- }
-
- public class ThirdParty
- {
- public string h323_address { get; set; }
- public string meeting_number { get; set; }
- public string service_provider { get; set; }
- public string sip_address { get; set; }
- }
-
- public class MeetingListItem
- {
- public string accessRole { get; set; }
- public string calendarChangeKey { get; set; }
- public string calendarID { get; set; }
- public bool checkIn { get; set; }
- public string creatorEmail { get; set; }
- public string creatorName { get; set; }
- public string endTime { get; set; }
- public string hostName { get; set; }
- public bool isInstantMeeting { get; set; }
- public bool isPrivate { get; set; }
- public string location { get; set; }
- public string meetingName { get; set; }
- public string meetingNumber { get; set; }
- public string scheduledFrom { get; set; }
- public string startTime { get; set; }
- public ThirdParty third_party { get; set; }
-
- public MeetingListItem()
- {
- third_party = new ThirdParty();
- }
- }
-
- public class InfoResult
- {
- public Info Info { get; set; }
- public bool am_i_original_host { get; set; }
- public string default_callin_country { get; set; }
- public string dialIn { get; set; }
- public string international_url { get; set; }
- public string invite_email_content { get; set; }
- public string invite_email_subject { get; set; }
- public bool is_callin_country_list_available { get; set; }
- public bool is_calling_room_system_enabled { get; set; }
- public bool is_toll_free_callin_list_available { get; set; }
- public bool is_view_only { get; set; }
- public bool is_waiting_room { get; set; }
- public bool is_webinar { get; set; }
- public string meeting_id { get; set; }
- public MeetingListItem meeting_list_item { get; set; }
- public string meeting_password { get; set; }
- public string meeting_type { get; set; }
- public int my_userid { get; set; }
- public int participant_id { get; set; }
- public string real_meeting_id { get; set; }
- public string schedule_option { get; set; }
- public string schedule_option2 { get; set; }
- public string support_callout_type { get; set; }
- public string toll_free_number { get; set; }
- public string user_type { get; set; }
-
- public InfoResult()
- {
- Info = new Info();
- meeting_list_item = new MeetingListItem();
- }
- }
-
- public class Phonebook
- {
- public List Contacts { get; set; }
- public int Limit { get; set; }
- public int Offset { get; set; }
- }
- }
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using Crestron.SimplSharp;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Devices.Common.Codec;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
+
+namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
+{
+ public enum eZoomRoomResponseType
+ {
+ zEvent,
+ zStatus,
+ zConfiguration,
+ zCommand
+ }
+
+ public abstract class NotifiableObject : INotifyPropertyChanged
+ {
+ #region INotifyPropertyChanged Members
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected void NotifyPropertyChanged(string propertyName)
+ {
+ if (PropertyChanged != null)
+ {
+ PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ #endregion
+ }
+
+ ///
+ /// Used to track the current status of a ZoomRoom
+ ///
+ public class ZoomRoomStatus
+ {
+ public zStatus.Login Login { get; set; }
+ public zStatus.SystemUnit SystemUnit { get; set; }
+ public zStatus.Phonebook Phonebook { get; set; }
+ public zStatus.Call Call { get; set; }
+ public zStatus.Capabilities Capabilities { get; set; }
+ public zStatus.Sharing Sharing { get; set; }
+ public zStatus.NumberOfScreens NumberOfScreens { get; set; }
+ public zStatus.Layout Layout { get; set; }
+ public zStatus.Video Video { get; set; }
+ public zStatus.CameraShare CameraShare { get; set; }
+ public List AudioInputs { get; set; }
+ public List AudioOuputs { get; set; }
+ public List Cameras { get; set; }
+ public zEvent.PhoneCallStatus PhoneCall { get; set; }
+
+ public ZoomRoomStatus()
+ {
+ Login = new zStatus.Login();
+ SystemUnit = new zStatus.SystemUnit();
+ Phonebook = new zStatus.Phonebook();
+ Call = new zStatus.Call();
+ Capabilities = new zStatus.Capabilities();
+ Sharing = new zStatus.Sharing();
+ NumberOfScreens = new zStatus.NumberOfScreens();
+ Layout = new zStatus.Layout();
+ Video = new zStatus.Video();
+ CameraShare = new zStatus.CameraShare();
+ AudioInputs = new List();
+ AudioOuputs = new List();
+ Cameras = new List();
+ PhoneCall = new zEvent.PhoneCallStatus();
+ }
+ }
+
+ ///
+ /// Used to track the current configuration of a ZoomRoom
+ ///
+ public class ZoomRoomConfiguration
+ {
+ public zConfiguration.Call Call { get; set; }
+ public zConfiguration.Audio Audio { get; set; }
+ public zConfiguration.Video Video { get; set; }
+ public zConfiguration.Client Client { get; set; }
+ public zConfiguration.Camera Camera { get; set; }
+
+ public ZoomRoomConfiguration()
+ {
+ Call = new zConfiguration.Call();
+ Audio = new zConfiguration.Audio();
+ Video = new zConfiguration.Video();
+ Client = new zConfiguration.Client();
+ Camera = new zConfiguration.Camera();
+ }
+ }
+
+ ///
+ /// Represents a response from a ZoomRoom system
+ ///
+ public class Response
+ {
+ public Status Status { get; set; }
+ public bool Sync { get; set; }
+ [JsonProperty("topKey")]
+ public string TopKey { get; set; }
+ [JsonProperty("type")]
+ public string Type { get; set; }
+
+ public Response()
+ {
+ Status = new Status();
+ }
+ }
+
+ public class Status
+ {
+ [JsonProperty("message")]
+ public string Message { get; set; }
+ [JsonProperty("state")]
+ public string State { get; set; }
+ }
+
+
+ ///
+ /// zStatus class stucture
+ ///
+ public class zStatus
+ {
+ public class Login
+ {
+ [JsonProperty("ZAAPI Release")]
+ public string ZAAPIRelease { get; set; }
+ [JsonProperty("Zoom Room Release")]
+ public string ZoomRoomRelease { get; set; }
+ }
+
+ public class SystemUnit
+ {
+ [JsonProperty("email")]
+ public string Email { get; set; }
+ [JsonProperty("login_type")]
+ public string LoginType { get; set; }
+ [JsonProperty("meeting_number")]
+ public string MeetingNumber { get; set; }
+ [JsonProperty("platform")]
+ public string Platform { get; set; }
+ [JsonProperty("room_info")]
+ public RoomInfo RoomInfo { get; set; }
+ [JsonProperty("room_version")]
+ public string RoomVersion { get; set; }
+
+ public SystemUnit()
+ {
+ RoomInfo = new RoomInfo();
+ }
+ }
+
+ public class RoomInfo
+ {
+ [JsonProperty("account_email")]
+ public string AccountEmail { get; set; }
+ [JsonProperty("display_version")]
+ public string DisplayVersion { get; set; }
+ [JsonProperty("is_auto_answer_enabled")]
+ public bool AutoAnswerIsEnabled { get; set; }
+ [JsonProperty("is_auto_answer_selected")]
+ public bool AutoAnswerIsSelected { get; set; }
+ [JsonProperty("room_name")]
+ public string RoomName { get; set; }
+ }
+
+ public class CloudPbxInfo
+ {
+ [JsonProperty("company_number")]
+ public string CompanyNumber { get; set; }
+ [JsonProperty("extension")]
+ public string Extension { get; set; }
+ [JsonProperty("isValid")]
+ public bool IsValid { get; set; }
+ }
+
+ public enum ePresence
+ {
+ PRESENCE_OFFLINE,
+ PRESENCE_ONLINE,
+ PRESENCE_AWAY,
+ PRESENCE_BUSY,
+ PRESENCE_DND
+ }
+
+ public class Contact
+ {
+ [JsonProperty("avatarURL")]
+ public string AvatarURL { get; set; }
+ [JsonProperty("cloud_pbx_info")]
+ public CloudPbxInfo CloudPbxInfo { get; set; }
+ [JsonProperty("email")]
+ public string Email { get; set; }
+ [JsonProperty("firstName")]
+ public string FirstName { get; set; }
+ [JsonProperty("index")]
+ public int Index { get; set; }
+ [JsonProperty("isLegacy")]
+ public bool IsLegacy { get; set; }
+ [JsonProperty("isZoomRoom")]
+ public bool IsZoomRoom { get; set; }
+ [JsonProperty("jid")]
+ public string Jid { get; set; }
+ [JsonProperty("lastName")]
+ public string LastName { get; set; }
+ [JsonProperty("onDesktop")]
+ public bool OnDesktop { get; set; }
+ [JsonProperty("onMobile")]
+ public bool OnMobile { get; set; }
+ [JsonProperty("phoneNumber")]
+ public string PhoneNumber { get; set; }
+ [JsonProperty("presence")]
+ public ePresence Presence { get; set; }
+ [JsonProperty("presence_status")]
+ public int PresenceStatus { get; set; }
+ [JsonProperty("screenName")]
+ public string ScreenName { get; set; }
+ [JsonProperty("sip_phone_number")]
+ public string SipPhoneNumber { get; set; }
+
+
+ public Contact()
+ {
+ CloudPbxInfo = new CloudPbxInfo();
+ }
+ }
+
+ ///
+ /// Used to be able to inplement IInvitableContact on DirectoryContact
+ ///
+ public class ZoomDirectoryContact : DirectoryContact, IInvitableContact
+ {
+
+ }
+
+ public class Phonebook
+ {
+ [JsonProperty("Contacts")]
+ public List Contacts { get; set; }
+
+ public Phonebook()
+ {
+ Contacts = new List();
+ }
+
+ ///
+ /// Converts from zStatus.Contact types to generic directory items
+ ///
+ ///
+ public static CodecDirectory ConvertZoomContactsToGeneric(List zoomContacts)
+ {
+ var directory = new CodecDirectory();
+
+ var folders = new List();
+
+ var roomFolder = new DirectoryFolder();
+
+ var contactFolder = new DirectoryFolder();
+
+ var contacts = new List();
+
+ // Check if there are any zoom rooms
+ var zoomRooms = zoomContacts.FindAll(c => c.IsZoomRoom);
+
+ if (zoomRooms.Count > 0)
+ {
+ // If so, setup a rooms and contacts folder and add them.
+ roomFolder.Name = "Rooms";
+ roomFolder.ParentFolderId = "root";
+ roomFolder.FolderId = "rooms";
+
+ contactFolder.Name = "Contacts";
+ contactFolder.ParentFolderId = "root";
+ contactFolder.FolderId = "contacts";
+
+ folders.Add(roomFolder);
+ folders.Add(contactFolder);
+
+ directory.AddFoldersToDirectory(folders);
+ }
+
+ try
+ {
+ if (zoomContacts.Count == 0) return directory;
+ {
+ foreach (Contact c in zoomContacts)
+ {
+ var contact = new ZoomDirectoryContact {Name = c.ScreenName, ContactId = c.Jid};
+
+ if (folders.Count > 0)
+ {
+ contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts";
+ }
+
+ contacts.Add(contact);
+ }
+
+ directory.AddContactsToDirectory(contacts);
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.Console(1, "Error converting Zoom Phonebook results to generic: {0}", e);
+ }
+
+ return directory;
+ }
+ }
+
+ public enum eCallStatus
+ {
+ UNKNOWN,
+ NOT_IN_MEETING,
+ CONNECTING_MEETING,
+ IN_MEETING,
+ LOGGED_OUT
+ }
+
+ public class ClosedCaption
+ {
+ public bool Available { get; set; }
+ }
+
+ public class Call : NotifiableObject
+ {
+ private eCallStatus _status;
+ private List _participants;
+
+ public bool IsInCall;
+
+ public eCallStatus Status
+ {
+ get
+ {
+ return _status;
+ }
+ set
+ {
+ if (value != _status)
+ {
+ _status = value;
+ IsInCall = _status == eCallStatus.IN_MEETING || _status == eCallStatus.CONNECTING_MEETING;
+ NotifyPropertyChanged("Status");
+ }
+ }
+ }
+ public ClosedCaption ClosedCaption { get; set; }
+ public List Participants
+ {
+ get
+ {
+ return _participants;
+ }
+ set
+ {
+ _participants = value;
+ NotifyPropertyChanged("Participants");
+ }
+ }
+ public zEvent.SharingState Sharing { get; set; }
+
+ public CallRecordInfo CallRecordInfo { get; set; }
+
+ private zCommand.InfoResult _info;
+
+ public zCommand.InfoResult Info
+ {
+ get
+ {
+ return _info;
+ }
+ set
+ {
+ _info = value;
+ NotifyPropertyChanged("Info");
+ }
+ }
+
+ public Call()
+ {
+ ClosedCaption = new ClosedCaption();
+ Participants = new List();
+ Sharing = new zEvent.SharingState();
+ CallRecordInfo = new CallRecordInfo();
+ Info = new zCommand.InfoResult();
+ }
+ }
+
+ public class Capabilities
+ {
+ public bool aec_Setting_Stored_In_ZR { get; set; }
+ public bool can_Dtmf_For_Invite_By_Phone { get; set; }
+ public bool can_Mute_On_Entry { get; set; }
+ public bool can_Ringing_In_Pstn_Call { get; set; }
+ public bool can_Switch_To_Specific_Camera { get; set; }
+ public bool is_Airhost_Disabled { get; set; }
+ public bool pstn_Call_In_Local_resentation { get; set; }
+ public bool support_Claim_Host { get; set; }
+ public bool support_Out_Room_Display { get; set; }
+ public bool support_Pin_And_Spotlight { get; set; }
+ public bool supports_Audio_Checkup { get; set; }
+ public bool supports_CheckIn { get; set; }
+ public bool supports_Cloud_PBX { get; set; }
+ public bool supports_Encrypted_Connection { get; set; }
+ public bool supports_Expel_User_Permanently { get; set; }
+ public bool supports_H323_DTMF { get; set; }
+ public bool supports_Hdmi_Cec_Control { get; set; }
+ public bool supports_Highly_Reverberant_Room { get; set; }
+ public bool supports_Loading_Contacts_Dynamically { get; set; }
+ public bool supports_Loading_Participants_Dynamically { get; set; }
+ public bool supports_Mic_Record_Test { get; set; }
+ public bool supports_Multi_Share { get; set; }
+ public bool supports_ShareCamera { get; set; }
+ public bool supports_Share_For_Floating_And_Content_Only { get; set; }
+ public bool supports_Sip_Call_out { get; set; }
+ public bool supports_Software_Audio_Processing { get; set; }
+ public bool supports_Web_Settings_Push { get; set; }
+ }
+
+ public class Sharing : NotifiableObject
+ {
+ private string _dispState;
+ private string _password;
+
+ public string directPresentationPairingCode { get; set; }
+ ///
+ /// Laptop client sharing key
+ ///
+ public string directPresentationSharingKey { get; set; }
+ public string dispState
+ {
+ get
+ {
+ return _dispState;
+ }
+ set
+ {
+ if (value != _dispState)
+ {
+ _dispState = value;
+ NotifyPropertyChanged("dispState");
+ }
+ }
+ }
+ public bool isAirHostClientConnected { get; set; }
+ public bool isBlackMagicConnected { get; set; }
+ public bool isBlackMagicDataAvailable { get; set; }
+ public bool isDirectPresentationConnected { get; set; }
+ public bool isSharingBlackMagic { get; set; }
+ ///
+ /// IOS Airplay code
+ ///
+ public string password
+ {
+ get
+ {
+ return _password;
+ }
+ set
+ {
+ if (value != _password)
+ {
+ _password = value;
+ NotifyPropertyChanged("password");
+ }
+ }
+ }
+ public string serverName { get; set; }
+ public string wifiName { get; set; }
+ }
+
+ public class NumberOfScreens
+ {
+ [JsonProperty("NumberOfCECScreens")]
+ public int NumOfCECScreens { get; set; }
+ [JsonProperty("NumberOfScreens")]
+ public int NumOfScreens { get; set; }
+ }
+
+ ///
+ /// AudioInputLine/AudioOutputLine/VideoCameraLine list item
+ ///
+ public class AudioVideoInputOutputLineItem
+ {
+ public string Alias { get; set; }
+ public string Name { get; set; }
+ public bool Selected { get; set; }
+ public bool combinedDevice { get; set; }
+ public string id { get; set; }
+ public bool manuallySelected { get; set; }
+ public int numberOfCombinedDevices { get; set; }
+ public int ptzComId { get; set; }
+ }
+
+ public class Video
+ {
+ public bool Optimizable { get; set; }
+ }
+
+ public class CameraShare : NotifiableObject
+ {
+ private bool _canControlCamera;
+ private bool _isSharing;
+
+ [JsonProperty("can_Control_Camera")]
+ public bool CanControlCamera
+ {
+ get
+ {
+ return _canControlCamera;
+ }
+ set
+ {
+ if (value != _canControlCamera)
+ {
+ _canControlCamera = value;
+ NotifyPropertyChanged("CanControlCamera");
+ }
+ }
+ }
+ public string id { get; set; }
+ public bool is_Mirrored { get; set; }
+ [JsonProperty("is_Sharing")]
+ public bool IsSharing
+ {
+ get
+ {
+ return _isSharing;
+ }
+ set
+ {
+ if (value != _isSharing)
+ {
+ _isSharing = value;
+ NotifyPropertyChanged("IsSharing");
+ }
+ }
+ }
+ public int pan_Tilt_Speed { get; set; }
+
+ }
+
+ public class Layout
+ {
+ public bool can_Adjust_Floating_Video { get; set; }
+ public bool can_Switch_Floating_Share_Content { get; set; }
+ public bool can_Switch_Share_On_All_Screens { get; set; }
+ public bool can_Switch_Speaker_View { get; set; }
+ public bool can_Switch_Wall_View { get; set; }
+ public bool is_In_First_Page { get; set; }
+ public bool is_In_Last_Page { get; set; }
+ public bool is_supported { get; set; }
+ public int video_Count_In_Current_Page { get; set; }
+ public string video_type { get; set; }
+ }
+
+ public class CallRecordInfo
+ {
+ public bool canRecord { get; set; }
+ public bool emailRequired { get; set; }
+ public bool amIRecording { get; set; }
+ public bool meetingIsBeingRecorded { get; set; }
+ }
+ }
+
+ ///
+ /// zEvent Class Structure
+ ///
+ public class zEvent
+ {
+ public class NeedWaitForHost
+ {
+ public bool Wait { get; set; }
+ }
+
+ public class IncomingCallIndication
+ {
+ public string callerJID { get; set; }
+ public string calleeJID { get; set; }
+ public string meetingID { get; set; }
+ public string password { get; set; }
+ public string meetingOption { get; set; }
+ public long MeetingNumber { get; set; }
+ public string callerName { get; set; }
+ public string avatarURL { get; set; }
+ public int lifeTime { get; set; }
+ public bool accepted { get; set; }
+ }
+
+ public class CallConnectError
+ {
+ public int error_code { get; set; }
+ public string error_message { get; set; }
+ }
+
+ public class CallDisconnect
+ {
+ public bool Successful
+ {
+ get
+ {
+ return success == "on";
+ }
+ }
+
+ public string success { get; set; }
+ }
+
+ public class Layout
+ {
+ public bool Sharethumb { get; set; }
+ }
+
+ public class Call
+ {
+ public Layout Layout { get; set; }
+ }
+
+ public class Client
+ {
+ public Call Call { get; set; }
+ }
+
+ public enum eSharingState
+ {
+ None,
+ Connecting,
+ Sending,
+ Receiving,
+ Send_Receiving
+ }
+
+ public class SharingState : NotifiableObject
+ {
+ private bool _paused;
+ private eSharingState _state;
+
+ public bool IsSharing;
+
+ [JsonProperty("paused")]
+ public bool Paused
+ {
+ get
+ {
+ return _paused;
+ }
+ set
+ {
+ if (value != _paused)
+ {
+ _paused = value;
+ NotifyPropertyChanged("Paused");
+ }
+ }
+ }
+ [JsonProperty("state")]
+ public eSharingState State
+ {
+ get
+ {
+ return _state;
+ }
+ set
+ {
+ if (value != _state)
+ {
+ _state = value;
+ IsSharing = _state == eSharingState.Sending;
+ NotifyPropertyChanged("State");
+ }
+ }
+ }
+ }
+
+ public class PinStatusOfScreenNotification
+ {
+ [JsonProperty("can_be_pinned")]
+ public bool CanBePinned { get; set; }
+ [JsonProperty("can_pin_share")]
+ public bool CanPinShare { get; set; }
+ [JsonProperty("pinned_share_source_id")]
+ public int PinnedShareSourceId { get; set; }
+ [JsonProperty("pinned_user_id")]
+ public int PinnedUserId { get; set; }
+ [JsonProperty("screen_index")]
+ public int ScreenIndex { get; set; }
+ [JsonProperty("screen_layout")]
+ public int ScreenLayout { get; set; }
+ [JsonProperty("share_source_type")]
+ public int ShareSourceType { get; set; }
+ [JsonProperty("why_cannot_pin_share")]
+ public string WhyCannotPinShare { get; set; }
+ }
+
+ public class PhoneCallStatus:NotifiableObject
+ {
+ private bool _isIncomingCall;
+ private string _peerDisplayName;
+ private string _peerNumber;
+
+ private bool _offHook;
+
+ public string CallId { get; set; }
+ public bool IsIncomingCall {
+ get { return _isIncomingCall; }
+ set
+ {
+ if(value == _isIncomingCall) return;
+
+ _isIncomingCall = value;
+ NotifyPropertyChanged("IsIncomingCall");
+ } }
+
+ public string PeerDisplayName
+ {
+ get { return _peerDisplayName; }
+ set
+ {
+ if (value == _peerDisplayName) return;
+ _peerDisplayName = value;
+ NotifyPropertyChanged("PeerDisplayName");
+ }
+ }
+
+ public string PeerNumber
+ {
+ get { return _peerNumber; }
+ set
+ {
+ if (value == _peerNumber) return;
+
+ _peerNumber = value;
+ NotifyPropertyChanged("PeerNumber");
+ }
+ }
+
+ public string PeerUri { get; set; }
+
+ private ePhoneCallStatus _status;
+ public ePhoneCallStatus Status
+ {
+ get { return _status; }
+ set
+ {
+ _status = value;
+ OffHook = _status == ePhoneCallStatus.PhoneCallStatus_Accepted ||
+ _status == ePhoneCallStatus.PhoneCallStatus_InCall ||
+ _status == ePhoneCallStatus.PhoneCallStatus_Init ||
+ _status == ePhoneCallStatus.PhoneCallStatus_Ringing;
+ }
+ }
+
+ public bool OffHook
+ {
+ get { return _offHook; }
+ set
+ {
+ if (value == _offHook) return;
+
+ _offHook = value;
+ NotifyPropertyChanged("OffHook");
+ }
+ }
+ }
+
+ public enum ePhoneCallStatus
+ {
+ PhoneCallStatus_Ringing,
+ PhoneCallStatus_Terminated,
+ PhoneCallStatus_Accepted,
+ PhoneCallStatus_InCall,
+ PhoneCallStatus_Init,
+ }
+ }
+
+ ///
+ /// zConfiguration class structure
+ ///
+ public class zConfiguration
+ {
+ public class Sharing
+ {
+ [JsonProperty("optimize_video_sharing")]
+ public bool OptimizeVideoSharing { get; set; }
+ }
+
+ public class Camera : NotifiableObject
+ {
+ private bool _mute;
+
+ public bool Mute
+ {
+ get { return _mute; }
+ set
+ {
+ Debug.Console(1, "Camera Mute response received: {0}", value);
+
+ if (value == _mute) return;
+
+ _mute = value;
+ NotifyPropertyChanged("Mute");
+ }
+ }
+ }
+
+ public class Microphone : NotifiableObject
+ {
+ private bool _mute;
+
+ public bool Mute
+ {
+ get
+ {
+ return _mute;
+ }
+ set
+ {
+ if(value != _mute)
+ {
+ _mute = value;
+ NotifyPropertyChanged("Mute");
+ }
+ }
+ }
+ }
+
+ public enum eLayoutStyle
+ {
+ Gallery,
+ Speaker,
+ Strip,
+ ShareAll
+ }
+
+ public enum eLayoutSize
+ {
+ Off,
+ Size1,
+ Size2,
+ Size3,
+ Strip
+ }
+
+ public enum eLayoutPosition
+ {
+ Center,
+ Up,
+ Right,
+ UpRight,
+ Down,
+ DownRight,
+ Left,
+ UpLeft,
+ DownLeft
+ }
+
+ public class Layout:NotifiableObject
+ {
+ public bool ShareThumb { get; set; }
+ public eLayoutStyle Style { get; set; }
+ public eLayoutSize Size { get; set; }
+
+ private eLayoutPosition _position;
+ public eLayoutPosition Position {
+ get { return _position; }
+ set
+ {
+ _position = value;
+ NotifyPropertyChanged("Position");
+ } }
+ }
+
+ public class Lock
+ {
+ public bool Enable { get; set; }
+ }
+
+ public class ClosedCaption
+ {
+ public bool Visible { get; set; }
+ public int FontSize { get; set; }
+ }
+
+ public class MuteUserOnEntry
+ {
+ public bool Enable { get; set; }
+ }
+
+ public class Call
+ {
+ public Sharing Sharing { get; set; }
+ public Camera Camera { get; set; }
+ public Microphone Microphone { get; set; }
+ public Layout Layout { get; set; }
+ public Lock Lock { get; set; }
+ public MuteUserOnEntry MuteUserOnEntry { get; set; }
+ public ClosedCaption ClosedCaption { get; set; }
+
+
+ public Call()
+ {
+ Sharing = new Sharing();
+ Camera = new Camera();
+ Microphone = new Microphone();
+ Layout = new Layout();
+ Lock = new Lock();
+ MuteUserOnEntry = new MuteUserOnEntry();
+ ClosedCaption = new ClosedCaption();
+ }
+ }
+
+ public class Audio
+ {
+ public Input Input { get; set; }
+ public Output Output { get; set; }
+
+ public Audio()
+ {
+ Input = new Input();
+ Output = new Output();
+ }
+ }
+
+ public class Input : Output
+ {
+ [JsonProperty("reduce_reverb")]
+ public bool ReduceReverb { get; set; }
+ }
+
+ public class Output : NotifiableObject
+ {
+ private int _volume;
+
+ [JsonProperty("volume")]
+ public int Volume
+ {
+ get
+ {
+ return _volume;
+ }
+ set
+ {
+ if (value != _volume)
+ {
+ _volume = value;
+ NotifyPropertyChanged("Volume");
+ }
+ }
+ }
+ [JsonProperty("selectedId")]
+ public string SelectedId { get; set; }
+ [JsonProperty("is_sap_disabled")]
+ public bool IsSapDisabled { get; set; }
+ }
+
+ public class Video : NotifiableObject
+ {
+ private bool _hideConfSelfVideo;
+
+ [JsonProperty("hide_conf_self_video")]
+ public bool HideConfSelfVideo
+ {
+ get
+ {
+ return _hideConfSelfVideo;
+ }
+ set
+ {
+ if (value != _hideConfSelfVideo)
+ {
+ _hideConfSelfVideo = value;
+ NotifyPropertyChanged("HideConfSelfVideo");
+ }
+ }
+ }
+
+ public VideoCamera Camera { get; set; }
+
+ public Video()
+ {
+ Camera = new VideoCamera();
+ }
+ }
+
+ public class VideoCamera : NotifiableObject
+ {
+ private string _selectedId;
+
+ [JsonProperty("selectedId")]
+ public string SelectedId {
+ get
+ {
+ return _selectedId;
+ }
+ set
+ {
+ if (value != _selectedId)
+ {
+ _selectedId = value;
+ NotifyPropertyChanged("SelectedId");
+ }
+ }
+
+ }
+ public bool Mirror { get; set; }
+ }
+
+ public class Client
+ {
+ public string appVersion { get; set; }
+ public string deviceSystem { get; set; }
+ }
+
+ }
+
+ ///
+ /// zCommand class structure
+ ///
+ public class zCommand
+ {
+ public class BookingsListResult
+ {
+ [JsonProperty("accessRole")]
+ public string AccessRole { get; set; }
+ [JsonProperty("calendarChangeKey")]
+ public string CalendarChangeKey { get; set; }
+ [JsonProperty("calendarID")]
+ public string CalendarId { get; set; }
+ [JsonProperty("checkIn")]
+ public bool CheckIn { get; set; }
+ [JsonProperty("creatorEmail")]
+ public string CreatorEmail { get; set; }
+ [JsonProperty("creatorName")]
+ public string CreatorName { get; set; }
+ [JsonProperty("endTime")]
+ public DateTime EndTime { get; set; }
+ [JsonProperty("hostName")]
+ public string HostName { get; set; }
+ [JsonProperty("isInstantMeeting")]
+ public bool IsInstantMeeting { get; set; }
+ [JsonProperty("isPrivate")]
+ public bool IsPrivate { get; set; }
+ [JsonProperty("location")]
+ public string Location { get; set; }
+ [JsonProperty("meetingName")]
+ public string MeetingName { get; set; }
+ [JsonProperty("meetingNumber")]
+ public string MeetingNumber { get; set; }
+ [JsonProperty("scheduledFrom")]
+ public string ScheduledFrom { get; set; }
+ [JsonProperty("startTime")]
+ public DateTime StartTime { get; set; }
+ [JsonProperty("third_party")]
+ public ThirdParty ThirdParty { get; set; }
+ }
+
+ public static List GetGenericMeetingsFromBookingResult(List bookings,
+ int minutesBeforeMeetingStart)
+ {
+ var rv = GetGenericMeetingsFromBookingResult(bookings);
+
+ foreach (var meeting in rv)
+ {
+ meeting.MinutesBeforeMeeting = minutesBeforeMeetingStart;
+ }
+
+ return rv;
+ }
+ ///
+ /// Extracts the necessary meeting values from the Zoom bookings response and converts them to the generic class
+ ///
+ ///
+ ///
+ public static List GetGenericMeetingsFromBookingResult(List bookings)
+ {
+ var meetings = new List();
+
+ if (Debug.Level > 0)
+ {
+ Debug.Console(1, "Meetings List:\n");
+ }
+
+ foreach (var b in bookings)
+ {
+ var meeting = new Meeting();
+
+ if (b.MeetingNumber != null)
+ meeting.Id = b.MeetingNumber;
+ if (b.CreatorName != null)
+ meeting.Organizer = b.CreatorName;
+ if (b.MeetingName != null)
+ meeting.Title = b.MeetingName;
+ //if (b.Agenda != null)
+ // meeting.Agenda = b.Agenda.Value;
+ if (b.StartTime != null)
+ meeting.StartTime = b.StartTime;
+ if (b.EndTime != null)
+ meeting.EndTime = b.EndTime;
+
+ meeting.Privacy = b.IsPrivate ? eMeetingPrivacy.Private : eMeetingPrivacy.Public;
+
+ // No meeting.Calls data exists for Zoom Rooms. Leaving out for now.
+ var now = DateTime.Now;
+ if (meeting.StartTime < now && meeting.EndTime < now)
+ {
+ Debug.Console(1, "Skipping meeting {0}. Meeting is in the past.", meeting.Title);
+ continue;
+ }
+
+ meetings.Add(meeting);
+
+ if (Debug.Level > 0)
+ {
+ Debug.Console(1, "Title: {0}, ID: {1}, Organizer: {2}", meeting.Title, meeting.Id, meeting.Organizer);
+ Debug.Console(1, " Start Time: {0}, End Time: {1}, Duration: {2}", meeting.StartTime, meeting.EndTime, meeting.Duration);
+ Debug.Console(1, " Joinable: {0}\n", meeting.Joinable);
+ }
+ }
+
+ meetings.OrderBy(m => m.StartTime);
+
+ return meetings;
+ }
+
+ public class HandStatus
+ {
+ [JsonProperty("is_raise_hand")]
+ public bool IsRaiseHand { get; set; }
+ [JsonProperty("optimize_vis_validideo_sharing")]
+ public string IsValid { get; set; }
+ [JsonProperty("time_stamp")]
+ public string TimeStamp { get; set; }
+ }
+
+ public class ListParticipant
+ {
+ [JsonProperty("audio_status state")]
+ public string AudioStatusState { get; set; }
+ [JsonProperty("audio_status type")]
+ public string AudioStatusType { get; set; }
+ [JsonProperty("avatar_url")]
+ public string AvatarUrl { get; set; }
+ [JsonProperty("camera_status am_i_controlling")]
+ public bool CameraStatusAmIControlling { get; set; }
+ [JsonProperty("camera_status can_i_request_control")]
+ public bool CameraStatusCanIRequestConrol { get; set; }
+ [JsonProperty("camera_status can_move_camera")]
+ public bool CameraStatusCanMoveCamera { get; set; }
+ [JsonProperty("camera_status can_switch_camera")]
+ public bool CameraStatusCanSwitchCamera { get; set; }
+ [JsonProperty("camera_status can_zoom_camera")]
+ public bool CameraStatusCanZoomCamera { get; set; }
+ [JsonProperty("can_edit_closed_caption")]
+ public bool CanEditClosedCaption { get; set; }
+ [JsonProperty("can_record")]
+ public bool CanRecord { get; set; }
+ [JsonProperty("event")]
+ public string Event { get; set; }
+ [JsonProperty("hand_status")]
+ public HandStatus HandStatus { get; set; }
+ [JsonProperty("isCohost")]
+ public bool IsCohost { get; set; }
+ [JsonProperty("is_client_support_closed_caption")]
+ public bool IsClientSupportClosedCaption { get; set; }
+ [JsonProperty("is_client_support_coHost")]
+ public bool IsClientSupportCoHost { get; set; }
+ [JsonProperty("is_host")]
+ public bool IsHost { get; set; }
+ [JsonProperty("is_myself")]
+ public bool IsMyself { get; set; }
+ [JsonProperty("is_recording")]
+ public bool IsRecording { get; set; }
+ [JsonProperty("is_video_can_mute_byHost")]
+ public bool IsVideoCanMuteByHost { get; set; }
+ [JsonProperty("is_video_can_unmute_byHost")]
+ public bool IsVideoCanUnmuteByHost { get; set; }
+ [JsonProperty("local_recording_disabled")]
+ public bool LocalRecordingDisabled { get; set; }
+ [JsonProperty("user_id")]
+ public int UserId { get; set; }
+ [JsonProperty("user_name")]
+ public string UserName { get; set; }
+ [JsonProperty("user_type")]
+ public string UserType { get; set; }
+ [JsonProperty("video_status has_source")]
+ public bool VideoStatusHasSource { get; set; }
+ [JsonProperty("video_status is_receiving")]
+ public bool VideoStatusIsReceiving { get; set; }
+ [JsonProperty("video_status is_sending")]
+ public bool VideoStatusIsSending { get; set; }
+
+ public ListParticipant()
+ {
+ HandStatus = new HandStatus();
+ }
+
+ public static List GetGenericParticipantListFromParticipantsResult(
+ List participants)
+ {
+ return
+ participants.Select(
+ p =>
+ new Participant
+ {
+ Name = p.UserName,
+ IsHost = p.IsHost,
+ CanMuteVideo = p.IsVideoCanMuteByHost,
+ CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
+ AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
+ VideoMuteFb = p.VideoStatusIsSending
+ }).ToList();
+ }
+ }
+
+ public class CallinCountryList
+ {
+ public int code { get; set; }
+ public string display_number { get; set; }
+ public string id { get; set; }
+ public string name { get; set; }
+ public string number { get; set; }
+ }
+
+ public class CalloutCountryList
+ {
+ public int code { get; set; }
+ public string display_number { get; set; }
+ public string id { get; set; }
+ public string name { get; set; }
+ public string number { get; set; }
+ }
+
+ public class TollFreeCallinList
+ {
+ public int code { get; set; }
+ public string display_number { get; set; }
+ public string id { get; set; }
+ public string name { get; set; }
+ public string number { get; set; }
+ }
+
+ public class Info
+ {
+ public List callin_country_list { get; set; }
+ public List callout_country_list { get; set; }
+ public List toll_free_callin_list { get; set; }
+ }
+
+ public class ThirdParty
+ {
+ public string h323_address { get; set; }
+ public string meeting_number { get; set; }
+ public string service_provider { get; set; }
+ public string sip_address { get; set; }
+ }
+
+ public class MeetingListItem
+ {
+ public string accessRole { get; set; }
+ public string calendarChangeKey { get; set; }
+ public string calendarID { get; set; }
+ public bool checkIn { get; set; }
+ public string creatorEmail { get; set; }
+ public string creatorName { get; set; }
+ public string endTime { get; set; }
+ public string hostName { get; set; }
+ public bool isInstantMeeting { get; set; }
+ public bool isPrivate { get; set; }
+ public string location { get; set; }
+ public string meetingName { get; set; }
+ public string meetingNumber { get; set; }
+ public string scheduledFrom { get; set; }
+ public string startTime { get; set; }
+ public ThirdParty third_party { get; set; }
+
+ public MeetingListItem()
+ {
+ third_party = new ThirdParty();
+ }
+ }
+
+ public class InfoResult
+ {
+ public Info Info { get; set; }
+ public bool am_i_original_host { get; set; }
+ public string default_callin_country { get; set; }
+ public string dialIn { get; set; }
+ public string international_url { get; set; }
+ public string invite_email_content { get; set; }
+ public string invite_email_subject { get; set; }
+ public bool is_callin_country_list_available { get; set; }
+ public bool is_calling_room_system_enabled { get; set; }
+ public bool is_toll_free_callin_list_available { get; set; }
+ public bool is_view_only { get; set; }
+ public bool is_waiting_room { get; set; }
+ public bool is_webinar { get; set; }
+ public string meeting_id { get; set; }
+ public MeetingListItem meeting_list_item { get; set; }
+ public string meeting_password { get; set; }
+ public string meeting_type { get; set; }
+ public int my_userid { get; set; }
+ public int participant_id { get; set; }
+ public string real_meeting_id { get; set; }
+ public string schedule_option { get; set; }
+ public string schedule_option2 { get; set; }
+ public string support_callout_type { get; set; }
+ public string toll_free_number { get; set; }
+ public string user_type { get; set; }
+
+ public InfoResult()
+ {
+ Info = new Info();
+ meeting_list_item = new MeetingListItem();
+ }
+ }
+
+ public class Phonebook
+ {
+ public List Contacts { get; set; }
+ public int Limit { get; set; }
+ public int Offset { get; set; }
+ }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
index 8f7b6876..980c7a61 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
@@ -1,2085 +1,2106 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-using Crestron.SimplSharpPro.CrestronThread;
-using Crestron.SimplSharpPro.DeviceSupport;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-using PepperDash.Essentials.Core.Config;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-using PepperDash.Essentials.Core.Routing;
-using PepperDash.Essentials.Devices.Common.Cameras;
-using PepperDash.Essentials.Devices.Common.Codec;
-using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
-using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
-using PepperDash_Essentials_Core.DeviceTypeInterfaces;
-
-namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
-{
- public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor,
- IRouting,
- IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraAutoMode,
- IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing
- {
- private const long MeetingRefreshTimer = 60000;
- private const uint DefaultMeetingDurationMin = 30;
- private const string Delimiter = "\x0D\x0A";
- private readonly CrestronQueue _receiveQueue;
-
-
- private readonly Thread _receiveThread;
-
- private readonly ZoomRoomSyncState _syncState;
- public bool CommDebuggingIsOn;
- private CodecDirectory _currentDirectoryResult;
- private uint _jsonCurlyBraceCounter;
- private bool _jsonFeedbackMessageIsIncoming;
- private StringBuilder _jsonMessage;
- private int _previousVolumeLevel;
- private CameraBase _selectedCamera;
-
- private readonly ZoomRoomPropertiesConfig _props;
-
- public ZoomRoom(DeviceConfig config, IBasicCommunication comm)
- : base(config)
- {
- _props = JsonConvert.DeserializeObject(config.Properties.ToString());
-
- // The queue that will collect the repsonses in the order they are received
- _receiveQueue = new CrestronQueue(1024);
-
- // The thread responsible for dequeuing and processing the messages
- _receiveThread = new Thread(o => ProcessQueue(), null) {Priority = Thread.eThreadPriority.MediumPriority};
-
- Communication = comm;
-
- if (_props.CommunicationMonitorProperties != null)
- {
- CommunicationMonitor = new GenericCommunicationMonitor(this, Communication,
- _props.CommunicationMonitorProperties);
- }
- else
- {
- CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 30000, 120000, 300000,
- "zStatus SystemUnit\r");
- }
-
- DeviceManager.AddDevice(CommunicationMonitor);
-
- Status = new ZoomRoomStatus();
-
- Configuration = new ZoomRoomConfiguration();
-
- CodecInfo = new ZoomRoomInfo(Status, Configuration);
-
- _syncState = new ZoomRoomSyncState(Key + "--Sync", this);
-
- _syncState.InitialSyncCompleted += SyncState_InitialSyncCompleted;
-
- PhonebookSyncState = new CodecPhonebookSyncState(Key + "--PhonebookSync");
-
- PortGather = new CommunicationGather(Communication, "\x0A") {IncludeDelimiter = true};
- PortGather.LineReceived += Port_LineReceived;
-
- CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd,
- eRoutingSignalType.Audio | eRoutingSignalType.Video,
- eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this);
-
- Output1 = new RoutingOutputPort(RoutingPortNames.AnyVideoOut,
- eRoutingSignalType.Audio | eRoutingSignalType.Video,
- eRoutingPortConnectionType.Hdmi, null, this);
-
- SelfviewIsOnFeedback = new BoolFeedback(SelfViewIsOnFeedbackFunc);
-
- CameraIsOffFeedback = new BoolFeedback(CameraIsOffFeedbackFunc);
-
- CameraAutoModeIsOnFeedback = new BoolFeedback(CameraAutoModeIsOnFeedbackFunc);
-
- CodecSchedule = new CodecScheduleAwareness(MeetingRefreshTimer);
-
- ReceivingContent = new BoolFeedback(FarEndIsSharingContentFeedbackFunc);
-
- SelfviewPipPositionFeedback = new StringFeedback(SelfviewPipPositionFeedbackFunc);
-
- SetUpFeedbackActions();
-
- Cameras = new List();
-
- SetUpDirectory();
-
- Participants = new CodecParticipants();
-
- SupportsCameraOff = _props.SupportsCameraOff;
- SupportsCameraAutoMode = _props.SupportsCameraAutoMode;
-
- PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc);
- CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc);
- CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc);
- }
-
- public CommunicationGather PortGather { get; private set; }
-
- public ZoomRoomStatus Status { get; private set; }
-
- public ZoomRoomConfiguration Configuration { get; private set; }
-
- //CTimer LoginMessageReceivedTimer;
- //CTimer RetryConnectionTimer;
-
- ///
- /// Gets and returns the scaled volume of the codec
- ///
- protected override Func VolumeLevelFeedbackFunc
- {
- get
- {
- return () => CrestronEnvironment.ScaleWithLimits(Configuration.Audio.Output.Volume, 100, 0, 65535, 0);
- }
- }
-
- protected override Func PrivacyModeIsOnFeedbackFunc
- {
- get { return () => Configuration.Call.Microphone.Mute; }
- }
-
- protected override Func StandbyIsOnFeedbackFunc
- {
- get { return () => false; }
- }
-
- protected override Func SharingSourceFeedbackFunc
- {
- get { return () => Status.Sharing.dispState; }
- }
-
- protected override Func SharingContentIsOnFeedbackFunc
- {
- get { return () => Status.Call.Sharing.IsSharing; }
- }
-
- protected Func FarEndIsSharingContentFeedbackFunc
- {
- get { return () => Status.Call.Sharing.State == zEvent.eSharingState.Receiving; }
- }
-
- protected override Func MuteFeedbackFunc
- {
- get { return () => Configuration.Audio.Output.Volume == 0; }
- }
-
- //protected Func RoomIsOccupiedFeedbackFunc
- //{
- // get
- // {
- // return () => false;
- // }
- //}
-
- //protected Func PeopleCountFeedbackFunc
- //{
- // get
- // {
- // return () => 0;
- // }
- //}
-
- protected Func SelfViewIsOnFeedbackFunc
- {
- get { return () => !Configuration.Video.HideConfSelfVideo; }
- }
-
- protected Func CameraIsOffFeedbackFunc
- {
- get { return () => Configuration.Call.Camera.Mute; }
- }
-
- protected Func CameraAutoModeIsOnFeedbackFunc
- {
- get { return () => false; }
- }
-
- protected Func SelfviewPipPositionFeedbackFunc
- {
- get { return () => _currentSelfviewPipPosition.Command; }
- }
-
- protected Func LocalLayoutFeedbackFunc
- {
- get { return () => ""; }
- }
-
- protected Func LocalLayoutIsProminentFeedbackFunc
- {
- get { return () => false; }
- }
-
-
- public RoutingInputPort CodecOsdIn { get; private set; }
- public RoutingOutputPort Output1 { get; private set; }
-
- #region ICommunicationMonitor Members
-
- public StatusMonitorBase CommunicationMonitor { get; private set; }
-
- #endregion
-
- #region IHasCodecCameras Members
-
- public event EventHandler CameraSelected;
-
- public List Cameras { get; private set; }
-
- public CameraBase SelectedCamera
- {
- get { return _selectedCamera; }
- private set
- {
- _selectedCamera = value;
- SelectedCameraFeedback.FireUpdate();
- ControllingFarEndCameraFeedback.FireUpdate();
-
- var handler = CameraSelected;
- if (handler != null)
- {
- handler(this, new CameraSelectedEventArgs(SelectedCamera));
- }
- }
- }
-
-
- public StringFeedback SelectedCameraFeedback { get; private set; }
-
- public void SelectCamera(string key)
- {
- if (Cameras == null)
- {
- return;
- }
-
- var camera = Cameras.FirstOrDefault(c => c.Key.IndexOf(key, StringComparison.OrdinalIgnoreCase) > -1);
- if (camera != null)
- {
- Debug.Console(1, this, "Selected Camera with key: '{0}'", camera.Key);
- SelectedCamera = camera;
- }
- else
- {
- Debug.Console(1, this, "Unable to select camera with key: '{0}'", key);
- }
- }
-
- public CameraBase FarEndCamera { get; private set; }
-
- public BoolFeedback ControllingFarEndCameraFeedback { get; private set; }
-
- #endregion
-
- #region IHasCodecSelfView Members
-
- public BoolFeedback SelfviewIsOnFeedback { get; private set; }
-
- public void SelfViewModeOn()
- {
- SendText("zConfiguration Video hide_conf_self_video: off");
- }
-
- public void SelfViewModeOff()
- {
- SendText("zConfiguration Video hide_conf_self_video: on");
- }
-
- public void SelfViewModeToggle()
- {
- if (SelfviewIsOnFeedback.BoolValue)
- {
- SelfViewModeOff();
- }
- else
- {
- SelfViewModeOn();
- }
- }
-
- #endregion
-
- #region IHasDirectoryHistoryStack Members
-
- public event EventHandler DirectoryResultReturned;
- public CodecDirectory DirectoryRoot { get; private set; }
-
- public CodecDirectory CurrentDirectoryResult
- {
- get { return _currentDirectoryResult; }
- }
-
- public CodecPhonebookSyncState PhonebookSyncState { get; private set; }
-
- public void SearchDirectory(string searchString)
- {
- var directoryResults = new CodecDirectory();
-
- directoryResults.AddContactsToDirectory(
- DirectoryRoot.CurrentDirectoryResults.FindAll(
- c => c.Name.IndexOf(searchString, 0, StringComparison.OrdinalIgnoreCase) > -1));
-
- DirectoryBrowseHistoryStack.Clear();
- _currentDirectoryResult = directoryResults;
-
- OnDirectoryResultReturned(directoryResults);
- }
-
- public void GetDirectoryFolderContents(string folderId)
- {
- var directoryResults = new CodecDirectory {ResultsFolderId = folderId};
-
- directoryResults.AddContactsToDirectory(
- DirectoryRoot.CurrentDirectoryResults.FindAll(c => c.ParentFolderId.Equals(folderId)));
-
- DirectoryBrowseHistoryStack.Push(_currentDirectoryResult);
-
- _currentDirectoryResult = directoryResults;
-
- OnDirectoryResultReturned(directoryResults);
- }
-
- public void SetCurrentDirectoryToRoot()
- {
- DirectoryBrowseHistoryStack.Clear();
-
- _currentDirectoryResult = DirectoryRoot;
-
- OnDirectoryResultReturned(DirectoryRoot);
- }
-
- public void GetDirectoryParentFolderContents()
- {
- if (DirectoryBrowseHistoryStack.Count == 0)
- {
- return;
- }
-
- var currentDirectory = DirectoryBrowseHistoryStack.Pop();
-
- _currentDirectoryResult = currentDirectory;
-
- OnDirectoryResultReturned(currentDirectory);
- }
-
- public BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; private set; }
-
- public List DirectoryBrowseHistory { get; private set; }
-
- public Stack DirectoryBrowseHistoryStack { get; private set; }
-
- #endregion
-
- #region IHasScheduleAwareness Members
-
- public CodecScheduleAwareness CodecSchedule { get; private set; }
-
- public void GetSchedule()
- {
- GetBookings();
- }
-
- #endregion
-
- #region IRouting Members
-
- public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
- {
- ExecuteSwitch(inputSelector);
- }
-
- #endregion
-
- private void SyncState_InitialSyncCompleted(object sender, EventArgs e)
- {
- SetUpRouting();
-
- SetIsReady();
- }
-
- private void SetUpCallFeedbackActions()
- {
- Status.Call.Sharing.PropertyChanged += (o, a) =>
- {
- if (a.PropertyName == "State")
- {
- SharingContentIsOnFeedback.FireUpdate();
- ReceivingContent.FireUpdate();
- }
- };
-
- Status.Call.PropertyChanged += (o, a) =>
- {
- if (a.PropertyName == "Info")
- {
- Debug.Console(1, this, "Updating Call Status");
- UpdateCallStatus();
- }
- };
- }
-
- ///
- /// Subscribes to the PropertyChanged events on the state objects and fires the corresponding feedbacks.
- ///
- private void SetUpFeedbackActions()
- {
- Configuration.Audio.Output.PropertyChanged += (o, a) =>
- {
- if (a.PropertyName == "Volume")
- {
- VolumeLevelFeedback.FireUpdate();
- MuteFeedback.FireUpdate();
- }
- };
-
- Configuration.Call.Microphone.PropertyChanged += (o, a) =>
- {
- if (a.PropertyName == "Mute")
- {
- PrivacyModeIsOnFeedback.FireUpdate();
- }
- };
-
- Configuration.Video.PropertyChanged += (o, a) =>
- {
- if (a.PropertyName == "HideConfSelfVideo")
- {
- SelfviewIsOnFeedback.FireUpdate();
- }
- };
- Configuration.Video.Camera.PropertyChanged += (o, a) =>
- {
- if (a.PropertyName == "SelectedId")
- {
- SelectCamera(Configuration.Video.Camera.SelectedId);
- // this will in turn fire the affected feedbacks
- }
- };
-
- Configuration.Call.Camera.PropertyChanged += (o, a) =>
- {
- Debug.Console(1, this, "Configuration.Call.Camera.PropertyChanged: {0}", a.PropertyName);
-
- if (a.PropertyName != "Mute") return;
-
- CameraIsOffFeedback.FireUpdate();
- CameraAutoModeIsOnFeedback.FireUpdate();
- };
-
- Configuration.Call.Layout.PropertyChanged += (o, a) =>
- {
- if (a.PropertyName != "Position") return;
-
- ComputeSelfviewPipStatus();
-
- SelfviewPipPositionFeedback.FireUpdate();
- };
-
- Status.Call.Sharing.PropertyChanged += (o, a) =>
- {
- if (a.PropertyName == "State")
- {
- SharingContentIsOnFeedback.FireUpdate();
- ReceivingContent.FireUpdate();
- }
- };
-
- Status.Call.PropertyChanged += (o, a) =>
- {
- if (a.PropertyName == "Info")
- {
- Debug.Console(1, this, "Updating Call Status");
- UpdateCallStatus();
- }
- };
-
- Status.Sharing.PropertyChanged += (o, a) =>
- {
- switch (a.PropertyName)
- {
- case "dispState":
- SharingSourceFeedback.FireUpdate();
- break;
- case "password":
- break;
- }
- };
-
- Status.PhoneCall.PropertyChanged += (o, a) =>
- {
- switch (a.PropertyName)
- {
- case "IsIncomingCall":
- Debug.Console(1, this, "Incoming Phone Call: {0}", Status.PhoneCall.IsIncomingCall);
- break;
- case "PeerDisplayName":
- Debug.Console(1, this, "Peer Display Name: {0}", Status.PhoneCall.PeerDisplayName);
- CallerIdNameFeedback.FireUpdate();
- break;
- case "PeerNumber":
- Debug.Console(1, this, "Peer Number: {0}", Status.PhoneCall.PeerNumber);
- CallerIdNumberFeedback.FireUpdate();
- break;
- case "OffHook":
- Debug.Console(1, this, "Phone is OffHook: {0}", Status.PhoneCall.OffHook);
- PhoneOffHookFeedback.FireUpdate();
- break;
- }
- };
- }
-
- private void SetUpDirectory()
- {
- DirectoryRoot = new CodecDirectory();
-
- DirectoryBrowseHistory = new List();
- DirectoryBrowseHistoryStack = new Stack();
-
- CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => _currentDirectoryResult != DirectoryRoot);
-
- CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
- }
-
- private void SetUpRouting()
- {
- // Set up input ports
- CreateOsdSource();
- InputPorts.Add(CodecOsdIn);
-
- // Set up output ports
- OutputPorts.Add(Output1);
- }
-
- ///
- /// Creates the fake OSD source, and connects it's AudioVideo output to the CodecOsdIn input
- /// to enable routing
- ///
- private void CreateOsdSource()
- {
- OsdSource = new DummyRoutingInputsDevice(Key + "[osd]");
- DeviceManager.AddDevice(OsdSource);
- var tl = new TieLine(OsdSource.AudioVideoOutputPort, CodecOsdIn);
- TieLineCollection.Default.Add(tl);
-
- //foreach(var input in Status.Video.
- }
-
- ///
- /// Starts the HTTP feedback server and syncronizes state of codec
- ///
- ///
- public override bool CustomActivate()
- {
- CrestronConsole.AddNewConsoleCommand(SetCommDebug, "SetCodecCommDebug", "0 for Off, 1 for on",
- ConsoleAccessLevelEnum.AccessOperator);
- if (!_props.DisablePhonebookAutoDownload)
- {
- CrestronConsole.AddNewConsoleCommand(s => SendText("zCommand Phonebook List Offset: 0 Limit: 512"),
- "GetZoomRoomContacts", "Triggers a refresh of the codec phonebook",
- ConsoleAccessLevelEnum.AccessOperator);
- }
-
- CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings",
- "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator);
-
- var socket = Communication as ISocketStatus;
- if (socket != null)
- {
- socket.ConnectionChange += socket_ConnectionChange;
- }
-
- CommDebuggingIsOn = false;
-
- Communication.Connect();
-
- CommunicationMonitor.Start();
-
- return base.CustomActivate();
- }
-
- public void SetCommDebug(string s)
- {
- if (s == "1")
- {
- CommDebuggingIsOn = true;
- Debug.Console(0, this, "Comm Debug Enabled.");
- }
- else
- {
- CommDebuggingIsOn = false;
- Debug.Console(0, this, "Comm Debug Disabled.");
- }
- }
-
- private void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
- {
- Debug.Console(1, this, "Socket status change {0}", e.Client.ClientStatus);
- if (e.Client.IsConnected)
- {
- }
- else
- {
- _syncState.CodecDisconnected();
- PhonebookSyncState.CodecDisconnected();
- }
- }
-
- public void SendText(string command)
- {
- if (CommDebuggingIsOn)
- {
- Debug.Console(1, this, "Sending: '{0}'", command);
- }
-
- Communication.SendText(command + Delimiter);
- }
-
- ///
- /// Gathers responses and enqueues them.
- ///
- ///
- ///
- private void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
- {
- //if (CommDebuggingIsOn)
- // Debug.Console(1, this, "Gathered: '{0}'", args.Text);
-
- _receiveQueue.Enqueue(args.Text);
-
- // If the receive thread has for some reason stopped, this will restart it
- if (_receiveThread.ThreadState != Thread.eThreadStates.ThreadRunning)
- {
- _receiveThread.Start();
- }
- }
-
-
- ///
- /// Runs in it's own thread to dequeue messages in the order they were received to be processed
- ///
- ///
- private object ProcessQueue()
- {
- try
- {
- while (true)
- {
- var message = _receiveQueue.Dequeue();
-
- ProcessMessage(message);
- }
- }
- catch (Exception e)
- {
- Debug.Console(1, this, "Error Processing Queue: {0}", e);
- }
-
- return null;
- }
-
-
- ///
- /// Queues the initial queries to be sent upon connection
- ///
- private void SetUpSyncQueries()
- {
- // zStatus
- _syncState.AddQueryToQueue("zStatus Call Status");
- _syncState.AddQueryToQueue("zStatus Audio Input Line");
- _syncState.AddQueryToQueue("zStatus Audio Output Line");
- _syncState.AddQueryToQueue("zStatus Video Camera Line");
- _syncState.AddQueryToQueue("zStatus Video Optimizable");
- _syncState.AddQueryToQueue("zStatus Capabilities");
- _syncState.AddQueryToQueue("zStatus Sharing");
- _syncState.AddQueryToQueue("zStatus CameraShare");
- _syncState.AddQueryToQueue("zStatus Call Layout");
- _syncState.AddQueryToQueue("zStatus Call ClosedCaption Available");
- _syncState.AddQueryToQueue("zStatus NumberOfScreens");
-
- // zConfiguration
-
- _syncState.AddQueryToQueue("zConfiguration Call Sharing optimize_video_sharing");
- _syncState.AddQueryToQueue("zConfiguration Call Microphone Mute");
- _syncState.AddQueryToQueue("zConfiguration Call Camera Mute");
- _syncState.AddQueryToQueue("zConfiguration Audio Input SelectedId");
- _syncState.AddQueryToQueue("zConfiguration Audio Input is_sap_disabled");
- _syncState.AddQueryToQueue("zConfiguration Audio Input reduce_reverb");
- _syncState.AddQueryToQueue("zConfiguration Audio Input volume");
- _syncState.AddQueryToQueue("zConfiguration Audio Output selectedId");
- _syncState.AddQueryToQueue("zConfiguration Audio Output volume");
- _syncState.AddQueryToQueue("zConfiguration Video hide_conf_self_video");
- _syncState.AddQueryToQueue("zConfiguration Video Camera selectedId");
- _syncState.AddQueryToQueue("zConfiguration Video Camera Mirror");
- _syncState.AddQueryToQueue("zConfiguration Client appVersion");
- _syncState.AddQueryToQueue("zConfiguration Client deviceSystem");
- _syncState.AddQueryToQueue("zConfiguration Call Layout ShareThumb");
- _syncState.AddQueryToQueue("zConfiguration Call Layout Style");
- _syncState.AddQueryToQueue("zConfiguration Call Layout Size");
- _syncState.AddQueryToQueue("zConfiguration Call Layout Position");
- _syncState.AddQueryToQueue("zConfiguration Call Lock Enable");
- _syncState.AddQueryToQueue("zConfiguration Call MuteUserOnEntry Enable");
- _syncState.AddQueryToQueue("zConfiguration Call ClosedCaption FontSize ");
- _syncState.AddQueryToQueue("zConfiguration Call ClosedCaption Visible");
-
- // zCommand
-
- if (!_props.DisablePhonebookAutoDownload)
- {
- _syncState.AddQueryToQueue("zCommand Phonebook List Offset: 0 Limit: 512");
- }
-
- _syncState.AddQueryToQueue("zCommand Bookings List");
- _syncState.AddQueryToQueue("zCommand Call ListParticipants");
- _syncState.AddQueryToQueue("zCommand Call Info");
-
-
- _syncState.StartSync();
- }
-
- ///
- /// Processes messages as they are dequeued
- ///
- ///
- private void ProcessMessage(string message)
- {
- // Counts the curly braces
- if (message.Contains("client_loop: send disconnect: Broken pipe"))
- {
- Debug.Console(0, this, Debug.ErrorLogLevel.Error,
- "Zoom Room Controller or App connected. Essentials will NOT control the Zoom Room until it is disconnected.");
-
- return;
- }
-
- if (message.Contains('{'))
- {
- _jsonCurlyBraceCounter++;
- }
-
- if (message.Contains('}'))
- {
- _jsonCurlyBraceCounter--;
- }
-
- Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter);
-
- if (!_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "{" + Delimiter)
- // Check for the beginning of a new JSON message
- {
- _jsonFeedbackMessageIsIncoming = true;
- _jsonCurlyBraceCounter = 1; // reset the counter for each new message
-
- _jsonMessage = new StringBuilder();
-
- _jsonMessage.Append(message);
-
- if (CommDebuggingIsOn)
- {
- Debug.Console(2, this, "Incoming JSON message...");
- }
-
- return;
- }
- if (_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "}" + Delimiter)
- // Check for the end of a JSON message
- {
- _jsonMessage.Append(message);
-
- if (_jsonCurlyBraceCounter == 0)
- {
- _jsonFeedbackMessageIsIncoming = false;
-
- if (CommDebuggingIsOn)
- {
- Debug.Console(2, this, "Complete JSON Received:\n{0}", _jsonMessage.ToString());
- }
-
- // Forward the complete message to be deserialized
- DeserializeResponse(_jsonMessage.ToString());
- }
-
- //JsonMessage = new StringBuilder();
- return;
- }
-
- // NOTE: This must happen after the above conditions have been checked
- // Append subsequent partial JSON fragments to the string builder
- if (_jsonFeedbackMessageIsIncoming)
- {
- _jsonMessage.Append(message);
-
- //Debug.Console(1, this, "Building JSON:\n{0}", JsonMessage.ToString());
- return;
- }
-
- if (CommDebuggingIsOn)
- {
- Debug.Console(1, this, "Non-JSON response: '{0}'", message);
- }
-
- _jsonCurlyBraceCounter = 0; // reset on non-JSON response
-
- if (!_syncState.InitialSyncComplete)
- {
- switch (message.Trim().ToLower()) // remove the whitespace
- {
- case "*r login successful":
- {
- _syncState.LoginMessageReceived();
-
- // Fire up a thread to send the intial commands.
- CrestronInvoke.BeginInvoke(o =>
- {
- Thread.Sleep(100);
- // disable echo of commands
- SendText("echo off");
- Thread.Sleep(100);
- // set feedback exclusions
- SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callin_country_list");
- Thread.Sleep(100);
- SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callout_country_list");
- Thread.Sleep(100);
-
- if (!_props.DisablePhonebookAutoDownload)
- {
- SendText("zFeedback Register Op: ex Path: /Event/Phonebook/AddedContact");
- }
- // switch to json format
- SendText("format json");
- });
-
- break;
- }
- }
- }
- }
-
- ///
- /// Deserializes a JSON formatted response
- ///
- ///
- private void DeserializeResponse(string response)
- {
- try
- {
- var trimmedResponse = response.Trim();
-
- if (trimmedResponse.Length <= 0)
- {
- return;
- }
-
- var message = JObject.Parse(trimmedResponse);
-
- var eType =
- (eZoomRoomResponseType)
- Enum.Parse(typeof (eZoomRoomResponseType), message["type"].Value(), true);
-
- var topKey = message["topKey"].Value();
-
- var responseObj = message[topKey];
-
- Debug.Console(1, "{0} Response Received. topKey: '{1}'\n{2}", eType, topKey, responseObj.ToString());
-
- switch (eType)
- {
- case eZoomRoomResponseType.zConfiguration:
- {
- switch (topKey.ToLower())
- {
- case "call":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Call);
-
- break;
- }
- case "audio":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Audio);
-
- break;
- }
- case "video":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Video);
-
- break;
- }
- case "client":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Client);
-
- break;
- }
- default:
- {
- break;
- }
- }
- break;
- }
- case eZoomRoomResponseType.zCommand:
- {
- switch (topKey.ToLower())
- {
- case "inforesult":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Info);
- break;
- }
- case "phonebooklistresult":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Phonebook);
-
- if (!PhonebookSyncState.InitialSyncComplete)
- {
- PhonebookSyncState.InitialPhonebookFoldersReceived();
- PhonebookSyncState.PhonebookRootEntriesReceived();
- PhonebookSyncState.SetPhonebookHasFolders(false);
- PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count);
- }
-
- var directoryResults =
- zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts);
-
- DirectoryRoot = directoryResults;
-
- _currentDirectoryResult = DirectoryRoot;
-
- OnDirectoryResultReturned(directoryResults);
-
- break;
- }
- case "listparticipantsresult":
- {
- Debug.Console(1, this, "JTokenType: {0}", responseObj.Type);
-
- switch (responseObj.Type)
- {
- case JTokenType.Array:
- Status.Call.Participants =
- JsonConvert.DeserializeObject>(
- responseObj.ToString());
- break;
- case JTokenType.Object:
- {
- // this is a single participant event notification
-
- var participant =
- JsonConvert.DeserializeObject(
- responseObj.ToString());
-
- if (participant != null)
- {
- switch (participant.Event)
- {
- case "ZRCUserChangedEventUserInfoUpdated":
- case "ZRCUserChangedEventLeftMeeting":
- {
- var existingParticipant =
- Status.Call.Participants.FirstOrDefault(
- p => p.UserId.Equals(participant.UserId));
-
- if (existingParticipant != null)
- {
- switch (participant.Event)
- {
- case "ZRCUserChangedEventLeftMeeting":
- Status.Call.Participants.Remove(existingParticipant);
- break;
- case "ZRCUserChangedEventUserInfoUpdated":
- JsonConvert.PopulateObject(responseObj.ToString(),
- existingParticipant);
- break;
- }
- }
- }
- break;
- case "ZRCUserChangedEventJoinedMeeting":
- Status.Call.Participants.Add(participant);
- break;
- }
- }
- }
- break;
- }
-
- var participants =
- zCommand.ListParticipant.GetGenericParticipantListFromParticipantsResult(
- Status.Call.Participants);
-
- Participants.CurrentParticipants = participants;
-
- PrintCurrentCallParticipants();
-
- break;
- }
- default:
- {
- break;
- }
- }
- break;
- }
- case eZoomRoomResponseType.zEvent:
- {
- switch (topKey.ToLower())
- {
- case "phonebook":
- {
- if (responseObj["Updated Contact"] != null)
- {
- var updatedContact =
- JsonConvert.DeserializeObject(
- responseObj["Updated Contact"].ToString());
-
- var existingContact =
- Status.Phonebook.Contacts.FirstOrDefault(c => c.Jid.Equals(updatedContact.Jid));
-
- if (existingContact != null)
- {
- // Update existing contact
- JsonConvert.PopulateObject(responseObj["Updated Contact"].ToString(),
- existingContact);
- }
- }
- else if (responseObj["Added Contact"] != null)
- {
- var jToken = responseObj["Updated Contact"];
- if (jToken != null)
- {
- var newContact =
- JsonConvert.DeserializeObject(
- jToken.ToString());
-
- // Add a new contact
- Status.Phonebook.Contacts.Add(newContact);
- }
- }
-
- break;
- }
- case "bookingslistresult":
- {
- if (!_syncState.InitialSyncComplete)
- {
- _syncState.LastQueryResponseReceived();
- }
-
- var codecBookings = JsonConvert.DeserializeObject>(
- responseObj.ToString());
-
- if (codecBookings != null && codecBookings.Count > 0)
- {
- CodecSchedule.Meetings = zCommand.GetGenericMeetingsFromBookingResult(
- codecBookings, CodecSchedule.MeetingWarningMinutes);
- }
-
- break;
- }
- case "bookings updated":
- {
- GetBookings();
-
- break;
- }
- case "sharingstate":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Sharing);
-
- SetLayout();
-
- break;
- }
- case "incomingcallindication":
- {
- var incomingCall =
- JsonConvert.DeserializeObject(responseObj.ToString());
-
- if (incomingCall != null)
- {
- var newCall = new CodecActiveCallItem
- {
- Direction = eCodecCallDirection.Incoming,
- Status = eCodecCallStatus.Ringing,
- Type = eCodecCallType.Unknown,
- Name = incomingCall.callerName,
- Id = incomingCall.callerJID
- };
-
- ActiveCalls.Add(newCall);
-
- OnCallStatusChange(newCall);
- }
-
- break;
- }
- case "treatedincomingcallindication":
- {
- var incomingCall =
- JsonConvert.DeserializeObject(responseObj.ToString());
-
- if (incomingCall != null)
- {
- var existingCall =
- ActiveCalls.FirstOrDefault(c => c.Id.Equals(incomingCall.callerJID));
-
- if (existingCall != null)
- {
- existingCall.Status = !incomingCall.accepted
- ? eCodecCallStatus.Disconnected
- : eCodecCallStatus.Connecting;
-
- OnCallStatusChange(existingCall);
- }
-
- UpdateCallStatus();
- }
-
- break;
- }
- case "calldisconnect":
- {
- var disconnectEvent =
- JsonConvert.DeserializeObject(responseObj.ToString());
-
- if (disconnectEvent.Successful)
- {
- if (ActiveCalls.Count > 0)
- {
- var activeCall = ActiveCalls.FirstOrDefault(c => c.IsActiveCall);
-
- if (activeCall != null)
- {
- activeCall.Status = eCodecCallStatus.Disconnected;
-
- OnCallStatusChange(activeCall);
- }
- }
- var emptyList = new List();
- Participants.CurrentParticipants = emptyList;
- }
-
- UpdateCallStatus();
- break;
- }
- case "callconnecterror":
- {
- UpdateCallStatus();
- break;
- }
- case "videounmuterequest":
- {
- // TODO: notify room of a request to unmute video
- break;
- }
- case "meetingneedspassword":
- {
- // TODO: notify user to enter a password
- break;
- }
- case "needwaitforhost":
- {
- var needWait =
- JsonConvert.DeserializeObject(responseObj.ToString());
-
- if (needWait.Wait)
- {
- // TODO: notify user to wait for host
- }
-
- break;
- }
- case "openvideofailforhoststop":
- {
- // TODO: notify user that host has disabled unmuting video
- break;
- }
- case "updatedcallrecordinfo":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.CallRecordInfo);
-
- break;
- }
- case "phonecallstatus":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall);
- break;
- }
- default:
- {
- break;
- }
- }
- break;
- }
- case eZoomRoomResponseType.zStatus:
- {
- switch (topKey.ToLower())
- {
- case "login":
- {
- _syncState.LoginMessageReceived();
-
- if (!_syncState.InitialQueryMessagesWereSent)
- {
- SetUpSyncQueries();
- }
-
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Login);
-
- break;
- }
- case "systemunit":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.SystemUnit);
-
- break;
- }
- case "call":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Call);
-
- UpdateCallStatus();
-
- break;
- }
- case "capabilities":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Capabilities);
- break;
- }
- case "sharing":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Sharing);
-
- break;
- }
- case "numberofscreens":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.NumberOfScreens);
- break;
- }
- case "video":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Video);
- break;
- }
- case "camerashare":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.CameraShare);
- break;
- }
- case "layout":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Layout);
- break;
- }
- case "audio input line":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.AudioInputs);
- break;
- }
- case "audio output line":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.AudioOuputs);
- break;
- }
- case "video camera line":
- {
- JsonConvert.PopulateObject(responseObj.ToString(), Status.Cameras);
-
- if (!_syncState.CamerasHaveBeenSetUp)
- {
- SetUpCameras();
- }
-
- break;
- }
- default:
- {
- break;
- }
- }
-
- break;
- }
- default:
- {
- Debug.Console(1, "Unknown Response Type:");
- break;
- }
- }
- }
- catch (Exception ex)
- {
- Debug.Console(1, this, "Error Deserializing feedback: {0}", ex);
- }
- }
-
- private void SetLayout()
- {
- if (!_props.AutoDefaultLayouts) return;
-
- if (
- (Status.Call.Sharing.State == zEvent.eSharingState.Receiving ||
- Status.Call.Sharing.State == zEvent.eSharingState.Sending))
- {
- SendText(String.Format("zconfiguration call layout style: {0}",
- _props.DefaultSharingLayout));
- }
- else
- {
- SendText(String.Format("zconfiguration call layout style: {0}",
- _props.DefaultCallLayout));
- }
- }
-
- public void PrintCurrentCallParticipants()
- {
- if (Debug.Level <= 0)
- {
- return;
- }
-
- Debug.Console(1, this, "****************************Call Participants***************************");
- foreach (var participant in Participants.CurrentParticipants)
- {
- Debug.Console(1, this, "Name: {0} Audio: {1} IsHost: {2}", participant.Name,
- participant.AudioMuteFb, participant.IsHost);
- }
- Debug.Console(1, this, "************************************************************************");
- }
-
- ///
- /// Retrieves bookings list
- ///
- private void GetBookings()
- {
- SendText("zCommand Bookings List");
- }
-
-
- ///
- /// Updates the current call status
- ///
- private void UpdateCallStatus()
- {
- if (Status.Call != null)
- {
- var callStatus = Status.Call.Status;
-
- // If not currently in a meeting, intialize the call object
- if (callStatus != zStatus.eCallStatus.IN_MEETING || callStatus != zStatus.eCallStatus.CONNECTING_MEETING)
- {
- Status.Call = new zStatus.Call {Status = callStatus};
-
- SetUpCallFeedbackActions();
- }
-
- if (ActiveCalls.Count == 0)
- {
- if (callStatus == zStatus.eCallStatus.CONNECTING_MEETING ||
- callStatus == zStatus.eCallStatus.IN_MEETING)
- {
- var newStatus = eCodecCallStatus.Unknown;
-
- switch (callStatus)
- {
- case zStatus.eCallStatus.CONNECTING_MEETING:
- newStatus = eCodecCallStatus.Connecting;
- break;
- case zStatus.eCallStatus.IN_MEETING:
- newStatus = eCodecCallStatus.Connected;
- break;
- }
-
- var newCall = new CodecActiveCallItem {Status = newStatus};
-
- ActiveCalls.Add(newCall);
-
- OnCallStatusChange(newCall);
- }
- }
- else
- {
- var existingCall = ActiveCalls.FirstOrDefault(c => !c.Status.Equals(eCodecCallStatus.Ringing));
-
- switch (callStatus)
- {
- case zStatus.eCallStatus.IN_MEETING:
- existingCall.Status = eCodecCallStatus.Connected;
- break;
- case zStatus.eCallStatus.NOT_IN_MEETING:
- existingCall.Status = eCodecCallStatus.Disconnected;
- break;
- }
-
- OnCallStatusChange(existingCall);
- }
- }
-
- Debug.Console(1, this, "****************************Active Calls*********************************");
-
- // Clean up any disconnected calls left in the list
- for (int i = 0; i < ActiveCalls.Count; i++)
- {
- var call = ActiveCalls[i];
-
- Debug.Console(1, this,
- @"Name: {0}
- ID: {1}
- IsActive: {2}
- Status: {3}
- Direction: {4}", call.Name, call.Id, call.IsActiveCall, call.Status, call.Direction);
-
- if (!call.IsActiveCall)
- {
- Debug.Console(1, this, "******Removing Inactive Call: {0}******", call.Name);
- ActiveCalls.Remove(call);
- }
- }
- Debug.Console(1, this, "**************************************************************************");
-
- //clear participants list after call cleanup
- if (ActiveCalls.Count == 0)
- {
- Participants.CurrentParticipants = new List();
- }
- }
-
- protected override void OnCallStatusChange(CodecActiveCallItem item)
- {
- base.OnCallStatusChange(item);
-
- if (_props.AutoDefaultLayouts)
- {
- SetLayout();
- }
- }
-
- public override void StartSharing()
- {
- SendText("zCommand Call Sharing HDMI Start");
- }
-
- ///
- /// Stops sharing the current presentation
- ///
- public override void StopSharing()
- {
- SendText("zCommand Call Sharing Disconnect");
- }
-
- public override void PrivacyModeOn()
- {
- SendText("zConfiguration Call Microphone Mute: on");
- }
-
- public override void PrivacyModeOff()
- {
- SendText("zConfiguration Call Microphone Mute: off");
- }
-
- public override void PrivacyModeToggle()
- {
- if (PrivacyModeIsOnFeedback.BoolValue)
- {
- PrivacyModeOff();
- }
- else
- {
- PrivacyModeOn();
- }
- }
-
- public override void MuteOff()
- {
- SetVolume((ushort) _previousVolumeLevel);
- }
-
- public override void MuteOn()
- {
- _previousVolumeLevel = Configuration.Audio.Output.Volume; // Store the previous level for recall
-
- SetVolume(0);
- }
-
- public override void MuteToggle()
- {
- if (MuteFeedback.BoolValue)
- {
- MuteOff();
- }
- else
- {
- MuteOn();
- }
- }
-
-
- ///
- /// Increments the voluem
- ///
- ///
- public override void VolumeUp(bool pressRelease)
- {
- // TODO: Implment volume decrement that calls SetVolume()
- }
-
- ///
- /// Decrements the volume
- ///
- ///
- public override void VolumeDown(bool pressRelease)
- {
- // TODO: Implment volume decrement that calls SetVolume()
- }
-
- ///
- /// Scales the level and sets the codec to the specified level within its range
- ///
- /// level from slider (0-65535 range)
- public override void SetVolume(ushort level)
- {
- var scaledLevel = CrestronEnvironment.ScaleWithLimits(level, 65535, 0, 100, 0);
- SendText(string.Format("zConfiguration Audio Output volume: {0}", scaledLevel));
- }
-
- ///
- /// Recalls the default volume on the codec
- ///
- public void VolumeSetToDefault()
- {
- }
-
- ///
- ///
- ///
- public override void StandbyActivate()
- {
- // No corresponding function on device
- }
-
- ///
- ///
- ///
- public override void StandbyDeactivate()
- {
- // No corresponding function on device
- }
-
- public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
- {
- LinkVideoCodecToApi(this, trilist, joinStart, joinMapKey, bridge);
- }
-
- public override void ExecuteSwitch(object selector)
- {
- var action = selector as Action;
- if (action == null)
- {
- return;
- }
-
- action();
- }
-
- public void AcceptCall()
- {
- var incomingCall =
- ActiveCalls.FirstOrDefault(
- c => c.Status.Equals(eCodecCallStatus.Ringing) && c.Direction.Equals(eCodecCallDirection.Incoming));
-
- AcceptCall(incomingCall);
- }
-
- public override void AcceptCall(CodecActiveCallItem call)
- {
- SendText(string.Format("zCommand Call Accept callerJID: {0}", call.Id));
-
- call.Status = eCodecCallStatus.Connected;
-
- OnCallStatusChange(call);
-
- UpdateCallStatus();
- }
-
- public void RejectCall()
- {
- var incomingCall =
- ActiveCalls.FirstOrDefault(
- c => c.Status.Equals(eCodecCallStatus.Ringing) && c.Direction.Equals(eCodecCallDirection.Incoming));
-
- RejectCall(incomingCall);
- }
-
- public override void RejectCall(CodecActiveCallItem call)
- {
- SendText(string.Format("zCommand Call Reject callerJID: {0}", call.Id));
-
- call.Status = eCodecCallStatus.Disconnected;
-
- OnCallStatusChange(call);
-
- UpdateCallStatus();
- }
-
- public override void Dial(Meeting meeting)
- {
- SendText(string.Format("zCommand Dial Start meetingNumber: {0}", meeting.Id));
- }
-
- public override void Dial(string number)
- {
- SendText(string.Format("zCommand Dial Join meetingNumber: {0}", number));
- }
-
- ///
- /// Invites a contact to either a new meeting (if not already in a meeting) or the current meeting.
- /// Currently only invites a single user
- ///
- ///
- public override void Dial(IInvitableContact contact)
- {
- var ic = contact as zStatus.ZoomDirectoryContact;
-
- if (ic != null)
- {
- Debug.Console(1, this, "Attempting to Dial (Invite): {0}", ic.Name);
-
- if (!IsInCall)
- {
- SendText(string.Format("zCommand Invite Duration: {0} user: {1}", DefaultMeetingDurationMin,
- ic.ContactId));
- }
- else
- {
- SendText(string.Format("zCommand Call invite user: {0}", ic.ContactId));
- }
- }
- }
-
- public override void EndCall(CodecActiveCallItem call)
- {
- SendText("zCommand Call Disconnect");
- }
-
- public override void EndAllCalls()
- {
- SendText("zCommand Call Disconnect");
- }
-
- public override void SendDtmf(string s)
- {
- SendDtmfToPhone(s);
- }
-
- ///
- /// Call when directory results are updated
- ///
- ///
- private void OnDirectoryResultReturned(CodecDirectory result)
- {
- CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
-
- // This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology
- var handler = DirectoryResultReturned;
- if (handler != null)
- {
- handler(this, new DirectoryEventArgs
- {
- Directory = result,
- DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue
- });
- }
-
- //PrintDirectory(result);
- }
-
- ///
- /// Builds the cameras List by using the Zoom Room zStatus.Cameras data. Could later be modified to build from config data
- ///
- private void SetUpCameras()
- {
- SelectedCameraFeedback = new StringFeedback(() => Configuration.Video.Camera.SelectedId);
-
- ControllingFarEndCameraFeedback = new BoolFeedback(() => SelectedCamera is IAmFarEndCamera);
-
- foreach (var cam in Status.Cameras)
- {
- var camera = new ZoomRoomCamera(cam.id, cam.Name, this);
-
- Cameras.Add(camera);
-
- if (cam.Selected)
- {
- SelectedCamera = camera;
- }
- }
-
- if (IsInCall)
- {
- UpdateFarEndCameras();
- }
-
- _syncState.CamerasSetUp();
- }
-
- ///
- /// Dynamically creates far end cameras for call participants who have far end control enabled.
- ///
- private void UpdateFarEndCameras()
- {
- // TODO: set up far end cameras for the current call
- }
-
- #region Implementation of IHasParticipants
-
- public CodecParticipants Participants { get; private set; }
-
- #endregion
-
- #region Implementation of IHasCameraOff
-
- public BoolFeedback CameraIsOffFeedback { get; private set; }
-
- public void CameraOff()
- {
- SendText("zConfiguration Call Camera Mute: On");
- }
-
- #endregion
-
- #region Implementation of IHasCameraAutoMode
-
- //Zoom doesn't support camera auto modes. Setting this to just unmute video
- public void CameraAutoModeOn()
- {
- throw new NotImplementedException("Zoom Room Doesn't support camera auto mode");
- }
-
- //Zoom doesn't support camera auto modes. Setting this to just unmute video
- public void CameraAutoModeOff()
- {
- SendText("zConfiguration Call Camera Mute: Off");
- }
-
- public void CameraAutoModeToggle()
- {
- throw new NotImplementedException("Zoom Room doesn't support camera auto mode");
- }
-
- public BoolFeedback CameraAutoModeIsOnFeedback { get; private set; }
-
- #endregion
-
- #region Implementation of IHasFarEndContentStatus
-
- public BoolFeedback ReceivingContent { get; private set; }
-
- #endregion
-
- #region Implementation of IHasSelfviewPosition
-
- private CodecCommandWithLabel _currentSelfviewPipPosition;
-
- public StringFeedback SelfviewPipPositionFeedback { get; private set; }
-
- public void SelfviewPipPositionSet(CodecCommandWithLabel position)
- {
- SendText(String.Format("zConfiguration Call Layout Position: {0}", position.Command));
- }
-
- public void SelfviewPipPositionToggle()
- {
- if (_currentSelfviewPipPosition != null)
- {
- var nextPipPositionIndex = SelfviewPipPositions.IndexOf(_currentSelfviewPipPosition) + 1;
-
- if (nextPipPositionIndex >= SelfviewPipPositions.Count)
- // Check if we need to loop back to the first item in the list
- nextPipPositionIndex = 0;
-
- SelfviewPipPositionSet(SelfviewPipPositions[nextPipPositionIndex]);
- }
- }
-
- public List SelfviewPipPositions = new List()
- {
- new CodecCommandWithLabel("UpLeft", "Center Left"),
- new CodecCommandWithLabel("UpRight", "Center Right"),
- new CodecCommandWithLabel("DownRight", "Lower Right"),
- new CodecCommandWithLabel("DownLeft", "Lower Left")
- };
-
- private void ComputeSelfviewPipStatus()
- {
- _currentSelfviewPipPosition =
- SelfviewPipPositions.FirstOrDefault(
- p => p.Command.ToLower().Equals(Configuration.Call.Layout.Position.ToString().ToLower()));
- }
-
- #endregion
-
- #region Implementation of IHasPhoneDialing
-
- private Func PhoneOffHookFeedbackFunc {get {return () => Status.PhoneCall.OffHook; }}
- private Func CallerIdNameFeedbackFunc { get { return () => Status.PhoneCall.PeerDisplayName; } }
- private Func