mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-15 05:24:58 +00:00
Compare commits
40 Commits
feature/Ge
...
1.5.9-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d0ea82402 | ||
|
|
2b06672800 | ||
|
|
68f6cf95b9 | ||
|
|
ffaff91ed2 | ||
|
|
d6a6791e7b | ||
|
|
aede5355b7 | ||
|
|
4db91b4f68 | ||
|
|
c31a2a09de | ||
|
|
9a3cde0a30 | ||
|
|
f22efb90c5 | ||
|
|
0192c50cf3 | ||
|
|
1a3e976b6c | ||
|
|
e54b48b2ae | ||
|
|
2d1f33a2a7 | ||
|
|
c64f1d4a55 | ||
|
|
0534a3631f | ||
|
|
df12c2b4c1 | ||
|
|
40376810bb | ||
|
|
a5ab1fdbf7 | ||
|
|
fbd43036a6 | ||
|
|
e37b35eeb9 | ||
|
|
537c6a42ff | ||
|
|
501de58282 | ||
|
|
ad905a6d04 | ||
|
|
9fb61c163f | ||
|
|
0e068f6e51 | ||
|
|
a059b2fd5b | ||
|
|
dc8ded20c3 | ||
|
|
1f576f778a | ||
|
|
c689893c94 | ||
|
|
0c9c0992cb | ||
|
|
1ddf4281c2 | ||
|
|
f83682960f | ||
|
|
eb8f3a4142 | ||
|
|
6887133a18 | ||
|
|
2a569b0a6a | ||
|
|
0c14163830 | ||
|
|
b6cf8d2a4b | ||
|
|
b11bed7cfa | ||
|
|
143355d29c |
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
@@ -12,14 +11,18 @@ using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Devices.Common;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
using PepperDash.Essentials.Core.Monitoring;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
using PepperDash.Essentials.Core.Touchpanels;
|
||||
using PepperDash.Essentials.DM;
|
||||
using PepperDash.Essentials.Fusion;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
//using PepperDash.Essentials.Room.MobileControl;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.DM.Config;
|
||||
using PepperDash_Essentials_Core.Fusion;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
@@ -53,20 +56,17 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (Debug.DoNotLoadOnNextBoot)
|
||||
{
|
||||
CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
|
||||
CrestronConsole.AddNewConsoleCommand(s => GoWithLoadDeferred(), "go", "Loads configuration file",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(PluginLoader.ReportAssemblyVersions, "reportversions", "Reports the versions of the loaded assemblies", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(PepperDash.Essentials.Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(BridgeHelper.PrintJoinMap, "getjoinmap", "map(s) for bridge or device on bridge [brKey [devKey]]", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s);
|
||||
}, "appdebugmessage", "Writes message to log", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s), "appdebugmessage", "Writes message to log", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
@@ -79,27 +79,29 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse
|
||||
("Current running configuration. This is the merged system and template configuration");
|
||||
CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject
|
||||
(ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented));
|
||||
CrestronConsole.ConsoleCommandResponse(JsonConvert.SerializeObject
|
||||
(ConfigReader.ConfigObject, Formatting.Indented));
|
||||
}, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
|
||||
"System URL: {0}\r" +
|
||||
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
|
||||
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
|
||||
"System URL: {0}\r" +
|
||||
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl), "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
|
||||
if (!Debug.DoNotLoadOnNextBoot)
|
||||
{
|
||||
GoWithLoad();
|
||||
GoWithLoad(null);
|
||||
return;
|
||||
}
|
||||
|
||||
SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
|
||||
}
|
||||
|
||||
private void GoWithLoadDeferred()
|
||||
{
|
||||
CrestronInvoke.BeginInvoke(GoWithLoad);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the program is running on a processor (appliance) or server (VC-4).
|
||||
///
|
||||
@@ -115,13 +117,11 @@ namespace PepperDash.Essentials
|
||||
|
||||
var dirSeparator = Global.DirectorySeparator;
|
||||
|
||||
string directoryPrefix;
|
||||
|
||||
directoryPrefix = Crestron.SimplSharp.CrestronIO.Directory.GetApplicationRootDirectory();
|
||||
var directoryPrefix = Directory.GetApplicationRootDirectory();
|
||||
|
||||
var fullVersion = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false);
|
||||
|
||||
AssemblyInformationalVersionAttribute fullVersionAtt = fullVersion[0] as AssemblyInformationalVersionAttribute;
|
||||
var fullVersionAtt = fullVersion[0] as AssemblyInformationalVersionAttribute;
|
||||
|
||||
Global.SetAssemblyVersion(fullVersionAtt.InformationalVersion);
|
||||
|
||||
@@ -172,7 +172,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// Begins the process of loading resources including plugins and configuration data
|
||||
/// </summary>
|
||||
public void GoWithLoad()
|
||||
public void GoWithLoad(object notUsed)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -321,10 +321,10 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
|
||||
// Build the processor wrapper class
|
||||
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));
|
||||
DeviceManager.AddDevice(new CrestronProcessor("processor"));
|
||||
|
||||
// Add global System Monitor device
|
||||
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor"));
|
||||
DeviceManager.AddDevice(new SystemMonitorController("systemMonitor"));
|
||||
|
||||
foreach (var devConf in ConfigReader.ConfigObject.Devices)
|
||||
{
|
||||
@@ -341,28 +341,28 @@ namespace PepperDash.Essentials
|
||||
devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper());
|
||||
|
||||
// Check if the processor is a DMPS model
|
||||
if (this.ControllerPrompt.IndexOf("dmps", StringComparison.OrdinalIgnoreCase) > -1)
|
||||
if (ControllerPrompt.IndexOf("dmps", StringComparison.OrdinalIgnoreCase) > -1)
|
||||
{
|
||||
Debug.Console(2, "Adding DmpsRoutingController for {0} to Device Manager.", this.ControllerPrompt);
|
||||
Debug.Console(2, "Adding DmpsRoutingController for {0} to Device Manager.", ControllerPrompt);
|
||||
|
||||
var propertiesConfig = JsonConvert.DeserializeObject<DM.Config.DmpsRoutingPropertiesConfig>(devConf.Properties.ToString());
|
||||
var propertiesConfig = JsonConvert.DeserializeObject<DmpsRoutingPropertiesConfig>(devConf.Properties.ToString());
|
||||
|
||||
if(propertiesConfig == null)
|
||||
propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig();
|
||||
propertiesConfig = new DmpsRoutingPropertiesConfig();
|
||||
|
||||
var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig);
|
||||
var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", ControllerPrompt, propertiesConfig);
|
||||
|
||||
DeviceManager.AddDevice(dmpsRoutingController);
|
||||
}
|
||||
else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1)
|
||||
else if (ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1)
|
||||
{
|
||||
Debug.Console(2, "MPC3 processor type detected. Adding Mpc3TouchpanelController.");
|
||||
|
||||
var butToken = devConf.Properties["buttons"];
|
||||
if (butToken != null)
|
||||
{
|
||||
var buttons = butToken.ToObject<Dictionary<string, Essentials.Core.Touchpanels.KeypadButton>>();
|
||||
var tpController = new Essentials.Core.Touchpanels.Mpc3TouchpanelController(devConf.Key, devConf.Name, Global.ControlSystem, buttons);
|
||||
var buttons = butToken.ToObject<Dictionary<string, KeypadButton>>();
|
||||
var tpController = new Mpc3TouchpanelController(devConf.Key, devConf.Name, Global.ControlSystem, buttons);
|
||||
DeviceManager.AddDevice(tpController);
|
||||
}
|
||||
else
|
||||
@@ -385,7 +385,7 @@ namespace PepperDash.Essentials
|
||||
IKeyed newDev = null;
|
||||
|
||||
if (newDev == null)
|
||||
newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf);
|
||||
newDev = Core.DeviceFactory.GetDevice(devConf);
|
||||
|
||||
//
|
||||
//if (newDev == null)
|
||||
@@ -449,46 +449,62 @@ namespace PepperDash.Essentials
|
||||
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
|
||||
if (room != null)
|
||||
{
|
||||
if (room is EssentialsHuddleSpaceRoom)
|
||||
var huddleRoom = room as EssentialsHuddleSpaceRoom;
|
||||
if (huddleRoom != null)
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
DeviceManager.AddDevice(huddleRoom);
|
||||
|
||||
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));
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(
|
||||
new EssentialsHuddleSpaceFusionController(huddleRoom, 0xf1));
|
||||
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
// Mobile Control bridge
|
||||
//var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom);
|
||||
//AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
|
||||
//DeviceManager.AddDevice(bridge);
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
CreateMobileControlBridge(huddleRoom);
|
||||
continue;
|
||||
}
|
||||
else if (room is EssentialsHuddleVtc1Room)
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
|
||||
var ddRoom = room as EssentialsDualDisplayRoom;
|
||||
//checking for dual display room first, as it inherits from EssentialsHuddleVtc1Room
|
||||
if (ddRoom != null)
|
||||
{
|
||||
DeviceManager.AddDevice(ddRoom);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Room is EssentialsDualDisplayRoom, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new EssentialsDualDisplayFusionController(ddRoom, 0xf1));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
// Mobile Control bridge
|
||||
//var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room);
|
||||
//AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
|
||||
//DeviceManager.AddDevice(bridge);
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
CreateMobileControlBridge(ddRoom);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
||||
var vtc1Room = room as EssentialsHuddleVtc1Room;
|
||||
if (vtc1Room != null)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion");
|
||||
DeviceManager.AddDevice(room);
|
||||
DeviceManager.AddDevice(vtc1Room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController(vtc1Room, 0xf1));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
|
||||
CreateMobileControlBridge(vtc1Room);
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion");
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
}
|
||||
else
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create room from config, key '{0}'",
|
||||
roomConfig.Key);
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded.");
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.Fusion;
|
||||
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
|
||||
namespace PepperDash.Essentials.Fusion
|
||||
{
|
||||
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
|
||||
public class EssentialsHuddleVtc1FusionController : EssentialsFusionSystemControllerBase
|
||||
{
|
||||
BooleanSigData CodecIsInCall;
|
||||
private BooleanSigData _codecIsInCall;
|
||||
|
||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
|
||||
: base(room, ipId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -33,11 +30,17 @@ namespace PepperDash.Essentials.Fusion
|
||||
/// <summary>
|
||||
/// Creates a static asset for the codec and maps the joins to the main room symbol
|
||||
/// </summary>
|
||||
void SetUpCodec()
|
||||
private void SetUpCodec()
|
||||
{
|
||||
try
|
||||
{
|
||||
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (essentialsHuddleVtc1Room == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var codec = essentialsHuddleVtc1Room.VideoCodec;
|
||||
|
||||
if (codec == null)
|
||||
{
|
||||
@@ -45,35 +48,46 @@ namespace PepperDash.Essentials.Fusion
|
||||
return;
|
||||
}
|
||||
|
||||
codec.UsageTracker = new UsageTracking(codec);
|
||||
codec.UsageTracker.UsageIsTracked = true;
|
||||
codec.UsageTracker = new UsageTracking(codec) {UsageIsTracked = true};
|
||||
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||
|
||||
var codecPowerOnAction = new Action<bool>(b => { if (!b) codec.StandbyDeactivate(); });
|
||||
var codecPowerOffAction = new Action<bool>(b => { if (!b) codec.StandbyActivate(); });
|
||||
var codecPowerOnAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
codec.StandbyDeactivate();
|
||||
}
|
||||
});
|
||||
var codecPowerOffAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
codec.StandbyActivate();
|
||||
}
|
||||
});
|
||||
|
||||
// Map FusionRoom Attributes:
|
||||
|
||||
// Codec volume
|
||||
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
|
||||
codecVolume.OutputSig.UserObject = new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
|
||||
codecVolume.OutputSig.UserObject =
|
||||
new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
|
||||
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
|
||||
|
||||
// In Call Status
|
||||
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
|
||||
codec.CallStatusChange += new EventHandler<PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
|
||||
|
||||
_codecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
|
||||
codec.CallStatusChange += codec_CallStatusChange;
|
||||
|
||||
// Online status
|
||||
if (codec is ICommunicationMonitor)
|
||||
{
|
||||
var c = codec as ICommunicationMonitor;
|
||||
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
|
||||
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
|
||||
c.CommunicationMonitor.StatusChange += (o, a) =>
|
||||
{
|
||||
codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
|
||||
};
|
||||
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1");
|
||||
c.CommunicationMonitor.StatusChange +=
|
||||
(o, a) => { codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; };
|
||||
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key,
|
||||
"Online - VC 1");
|
||||
}
|
||||
|
||||
// Codec IP Address
|
||||
@@ -83,10 +97,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
string codecIpAddress = string.Empty;
|
||||
int codecIpPort = 0;
|
||||
|
||||
StringSigData codecIpAddressSig;
|
||||
StringSigData codecIpPortSig;
|
||||
|
||||
if(codecComm is GenericSshClient)
|
||||
if (codecComm is GenericSshClient)
|
||||
{
|
||||
codecIpAddress = (codecComm as GenericSshClient).Hostname;
|
||||
codecIpPort = (codecComm as GenericSshClient).Port;
|
||||
@@ -101,14 +112,16 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
if (codecHasIpInfo)
|
||||
{
|
||||
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly);
|
||||
StringSigData codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC",
|
||||
eSigIoMask.InputSigOnly);
|
||||
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
|
||||
|
||||
codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly);
|
||||
StringSigData codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC",
|
||||
eSigIoMask.InputSigOnly);
|
||||
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
|
||||
}
|
||||
|
||||
var tempAsset = new FusionAsset();
|
||||
FusionAsset tempAsset;
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
|
||||
|
||||
@@ -119,11 +132,13 @@ namespace PepperDash.Essentials.Fusion
|
||||
else
|
||||
{
|
||||
// Create a new asset
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", "");
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name,
|
||||
"Codec", "");
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
||||
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
|
||||
tempAsset.InstanceId);
|
||||
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
|
||||
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
|
||||
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
|
||||
@@ -139,56 +154,31 @@ namespace PepperDash.Essentials.Fusion
|
||||
}
|
||||
}
|
||||
|
||||
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
|
||||
private void codec_CallStatusChange(object sender, Core.Devices.Codec.CodecCallStatusItemChangeEventArgs e)
|
||||
{
|
||||
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (essentialsHuddleVtc1Room == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var codec = essentialsHuddleVtc1Room.VideoCodec;
|
||||
|
||||
CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
||||
_codecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
||||
}
|
||||
|
||||
// These methods are overridden because they access the room class which is of a different type
|
||||
|
||||
protected override void CreateSymbolAndBasicSigs(uint ipId)
|
||||
{
|
||||
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
||||
|
||||
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
|
||||
|
||||
FusionRoom.Register();
|
||||
|
||||
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
|
||||
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange;
|
||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
|
||||
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
// Room to fusion room
|
||||
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
|
||||
|
||||
// Moved to
|
||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly);
|
||||
// Don't think we need to get current status of this as nothing should be alive yet.
|
||||
(Room as EssentialsHuddleVtc1Room).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;
|
||||
}
|
||||
|
||||
protected override void SetUpSources()
|
||||
{
|
||||
// Sources
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey);
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
|
||||
if (essentialsHuddleVtc1Room == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey(essentialsHuddleVtc1Room.SourceListKey);
|
||||
if (dict != null)
|
||||
{
|
||||
// NEW PROCESS:
|
||||
@@ -200,7 +190,9 @@ namespace PepperDash.Essentials.Fusion
|
||||
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);
|
||||
@@ -210,7 +202,9 @@ namespace PepperDash.Essentials.Fusion
|
||||
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 Core.Devices.Laptop);
|
||||
@@ -220,26 +214,22 @@ namespace PepperDash.Essentials.Fusion
|
||||
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 10) // We only have ten spots???
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var kvp in dict)
|
||||
{
|
||||
var usageDevice = kvp.Value.SourceDevice as IUsageTracking;
|
||||
|
||||
if (usageDevice != null)
|
||||
{
|
||||
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device);
|
||||
usageDevice.UsageTracker.UsageIsTracked = true;
|
||||
usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var usageDevice in dict.Select(kvp => kvp.Value.SourceDevice).OfType<IUsageTracking>())
|
||||
{
|
||||
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 as EssentialsHuddleVtc1Room).SourceListKey, Room.Key);
|
||||
essentialsHuddleVtc1Room.SourceListKey, Room.Key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,40 +243,60 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
// Consider updating this in multiple display systems
|
||||
|
||||
foreach (DisplayBase display in displays)
|
||||
foreach (var display in displays.Cast<DisplayBase>())
|
||||
{
|
||||
display.UsageTracker = new UsageTracking(display);
|
||||
display.UsageTracker.UsageIsTracked = true;
|
||||
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
||||
display.UsageTracker = new UsageTracking(display) {UsageIsTracked = true};
|
||||
display.UsageTracker.DeviceUsageEnded +=
|
||||
UsageTracker_DeviceUsageEnded;
|
||||
}
|
||||
|
||||
var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (essentialsHuddleVtc1Room == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var defaultDisplay = essentialsHuddleVtc1Room.DefaultDisplay as DisplayBase;
|
||||
if (defaultDisplay == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
|
||||
return;
|
||||
}
|
||||
|
||||
var dispPowerOnAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOn(); });
|
||||
var dispPowerOffAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOff(); });
|
||||
var dispPowerOnAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
defaultDisplay.PowerOn();
|
||||
}
|
||||
});
|
||||
var dispPowerOffAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
defaultDisplay.PowerOff();
|
||||
}
|
||||
});
|
||||
|
||||
// Display to fusion room sigs
|
||||
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
if (defaultDisplay is IDisplayUsage)
|
||||
{
|
||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
|
||||
}
|
||||
|
||||
|
||||
MapDisplayToRoomJoins(1, 158, defaultDisplay);
|
||||
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
|
||||
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))
|
||||
{
|
||||
@@ -295,11 +305,13 @@ namespace PepperDash.Essentials.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;
|
||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
@@ -312,30 +324,59 @@ namespace PepperDash.Essentials.Fusion
|
||||
{
|
||||
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
|
||||
{
|
||||
string displayName = string.Format("Display {0} - ", displayIndex);
|
||||
var displayName = string.Format("Display {0} - ", displayIndex);
|
||||
|
||||
|
||||
if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay)
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (essentialsHuddleVtc1Room == null || display != essentialsHuddleVtc1Room.DefaultDisplay)
|
||||
{
|
||||
// Power on
|
||||
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
|
||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
|
||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
|
||||
// Power Off
|
||||
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
|
||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
|
||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
|
||||
// Current Source
|
||||
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
|
||||
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ;
|
||||
return;
|
||||
}
|
||||
// Power on
|
||||
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint) joinOffset, displayName + "Power On",
|
||||
eSigIoMask.InputOutputSig);
|
||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
display.PowerOn();
|
||||
}
|
||||
});
|
||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
|
||||
// Power Off
|
||||
|
||||
FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 1,
|
||||
displayName + "Power Off", eSigIoMask.InputOutputSig);
|
||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
display.PowerOff();
|
||||
}
|
||||
});
|
||||
|
||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
|
||||
// Current Source
|
||||
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 8,
|
||||
displayName + "Source None", eSigIoMask.InputOutputSig);
|
||||
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var huddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (huddleVtc1Room != null)
|
||||
{
|
||||
huddleVtc1Room.RunRouteAction("roomOff", Room.SourceListKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,25 +138,14 @@
|
||||
<Compile Include="ControlSystem.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleVtc1FusionController.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Room\Config\EssentialsDualDisplayRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsNDisplayRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\DDVC01RoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsPresentationPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsHuddleRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomEmergencyConfig.cs" />
|
||||
<Compile Include="Room\Emergency\EsentialsRoomEmergencyContactClosure.cs" />
|
||||
<Compile Include="Room\Types\EssentialsDualDisplayRoom.cs" />
|
||||
<Compile Include="Room\Types\EssentialsHuddleVtc1Room.cs" />
|
||||
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomConfig.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />
|
||||
<Compile Include="UIDrivers\EssentialsDualDisplay\EssentialsDualDisplayPanelAvFunctionsDriver.cs" />
|
||||
<Compile Include="UIDrivers\Essentials\EssentialsHeaderDriver.cs" />
|
||||
<Compile Include="UIDrivers\IHasCalendarButton.cs" />
|
||||
<Compile Include="UIDrivers\JoinedSigInterlock.cs" />
|
||||
<Compile Include="UIDrivers\SigInterlock.cs" />
|
||||
<Compile Include="UIDrivers\EssentialsHuddleVTC\EssentialsHuddlePresentationUiDriver.cs" />
|
||||
<Compile Include="UIDrivers\EssentialsHuddle\EssentialsHuddleTechPageDriver.cs" />
|
||||
<Compile Include="UI\HttpLogoServer.cs" />
|
||||
<Compile Include="UI\SmartObjectHeaderButtonList.cs" />
|
||||
@@ -178,7 +167,6 @@
|
||||
<Compile Include="UI\JoinConstants\UIBoolJoin.cs" />
|
||||
<Compile Include="UI\DualDisplaySourceSRLController.cs" />
|
||||
<Compile Include="UI\SubpageReferenceListActivityItem.cs" />
|
||||
<Compile Include="Room\Types\EssentialsHuddleSpaceRoom.cs" />
|
||||
<Compile Include="UI\EssentialsTouchpanelController.cs" />
|
||||
<Compile Include="UI\SubpageReferenceListSourceItem.cs" />
|
||||
<None Include="app.config" />
|
||||
@@ -215,6 +203,9 @@
|
||||
<Name>Essentials Devices Common</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Room\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
@@ -77,9 +74,8 @@ namespace PepperDash.Essentials
|
||||
var leftDisp = LeftDisplay as DisplayBase;
|
||||
var rightDisp = RightDisplay as DisplayBase;
|
||||
if (leftDisp != null && RightDisplay != null)
|
||||
return leftDisp.IsWarmingUpFeedback.BoolValue || rightDisp.IsWarmingUpFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
return rightDisp != null && (leftDisp.IsWarmingUpFeedback.BoolValue || rightDisp.IsWarmingUpFeedback.BoolValue);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -96,9 +92,8 @@ namespace PepperDash.Essentials
|
||||
var leftDisp = LeftDisplay as DisplayBase;
|
||||
var rightDisp = RightDisplay as DisplayBase;
|
||||
if (leftDisp != null && RightDisplay != null)
|
||||
return leftDisp.IsCoolingDownFeedback.BoolValue || rightDisp.IsCoolingDownFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
return rightDisp != null && (leftDisp.IsCoolingDownFeedback.BoolValue || rightDisp.IsCoolingDownFeedback.BoolValue);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -120,7 +115,7 @@ namespace PepperDash.Essentials
|
||||
/// If room is off, enables power on to last source. Default true
|
||||
/// </summary>
|
||||
public bool EnablePowerOnToLastSource { get; set; }
|
||||
string LastSourceKey;
|
||||
string _lastSourceKey;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
|
||||
@@ -128,27 +123,27 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public IBasicVolumeControls CurrentVolumeControls
|
||||
{
|
||||
get { return _CurrentAudioDevice; }
|
||||
get { return _currentAudioDevice; }
|
||||
set
|
||||
{
|
||||
if (value == _CurrentAudioDevice) return;
|
||||
if (value == _currentAudioDevice) return;
|
||||
|
||||
var oldDev = _CurrentAudioDevice;
|
||||
var oldDev = _currentAudioDevice;
|
||||
// derigister this room from the device, if it can
|
||||
if (oldDev is IInUseTracking)
|
||||
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||
var handler = CurrentVolumeDeviceChange;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||
_CurrentAudioDevice = value;
|
||||
_currentAudioDevice = value;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||
// register this room with new device, if it can
|
||||
if (_CurrentAudioDevice is IInUseTracking)
|
||||
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||
if (_currentAudioDevice is IInUseTracking)
|
||||
(_currentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||
}
|
||||
}
|
||||
IBasicVolumeControls _CurrentAudioDevice;
|
||||
IBasicVolumeControls _currentAudioDevice;
|
||||
|
||||
/// <summary>
|
||||
/// "codecOsd"
|
||||
@@ -161,7 +156,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||
|
||||
CCriticalSection SourceSelectLock = new CCriticalSection();
|
||||
readonly CCriticalSection _sourceSelectLock = new CCriticalSection();
|
||||
|
||||
public EssentialsDualDisplayRoom(DeviceConfig config)
|
||||
: base(config)
|
||||
@@ -196,12 +191,12 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
|
||||
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
||||
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
|
||||
VideoCodecBase;
|
||||
if (VideoCodec == null)
|
||||
throw new ArgumentNullException("codec cannot be null");
|
||||
|
||||
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
||||
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
|
||||
AudioCodecBase;
|
||||
if (AudioCodec == null)
|
||||
Debug.Console(0, this, "No Audio Codec Found");
|
||||
|
||||
@@ -217,8 +212,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||
if (DefaultAudioDevice != null)
|
||||
DefaultVolumeControls = DefaultAudioDevice;
|
||||
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
@@ -233,12 +228,12 @@ namespace PepperDash.Essentials
|
||||
InitializeDisplay(rightDisp);
|
||||
|
||||
// Get Microphone Privacy object, if any
|
||||
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||
MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
|
||||
|
||||
// Get emergency object, if any
|
||||
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||
Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Emergency Config evaluated.");
|
||||
|
||||
@@ -254,23 +249,20 @@ namespace PepperDash.Essentials
|
||||
if (VideoCodec != null)
|
||||
inVideoCall = VideoCodec.IsInCall;
|
||||
|
||||
if (inAudioCall || inVideoCall)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return inAudioCall || inVideoCall;
|
||||
});
|
||||
|
||||
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
VideoCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
|
||||
|
||||
if (AudioCodec != null)
|
||||
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
AudioCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
|
||||
|
||||
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
|
||||
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => IsSharingFeedback.FireUpdate();
|
||||
|
||||
// link privacy to VC (for now?)
|
||||
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => PrivacyModeIsOnFeedback.FireUpdate();
|
||||
|
||||
CallTypeFeedback = new IntFeedback(() => 0);
|
||||
|
||||
@@ -300,13 +292,18 @@ namespace PepperDash.Essentials
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
if (!IsWarmingUpFeedback.BoolValue)
|
||||
(CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||
};
|
||||
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
if (IsWarmingUpFeedback.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var basicVolumeWithFeedback = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
if (basicVolumeWithFeedback != null)
|
||||
{
|
||||
basicVolumeWithFeedback.SetVolume(DefaultVolume);
|
||||
}
|
||||
};
|
||||
disp.IsCoolingDownFeedback.OutputChange += (o, a) => IsCoolingDownFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,13 +321,13 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
// Add Occupancy object from config
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
|
||||
this.LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||
SourceListKey = PropertiesConfig.SourceListKey;
|
||||
DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
@@ -376,6 +373,7 @@ namespace PepperDash.Essentials
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="sourceListKey"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||
{
|
||||
RunRouteAction(routeKey, sourceListKey, null);
|
||||
@@ -385,14 +383,17 @@ namespace PepperDash.Essentials
|
||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||
/// route or commands
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="sourceListKey"></param>
|
||||
/// <param name="successCallback"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
|
||||
{
|
||||
// Run this on a separate thread
|
||||
new CTimer(o =>
|
||||
//new CTimer
|
||||
CrestronInvoke.BeginInvoke(o =>
|
||||
{
|
||||
// try to prevent multiple simultaneous selections
|
||||
SourceSelectLock.TryEnter();
|
||||
_sourceSelectLock.TryEnter();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -414,9 +415,9 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
|
||||
// End usage timer on last source
|
||||
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||
if (!string.IsNullOrEmpty(_lastSourceKey))
|
||||
{
|
||||
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
|
||||
var usageLastSource = dict[_lastSourceKey].SourceDevice as IUsageTracking;
|
||||
if (usageLastSource != null && usageLastSource.UsageTracker != null)
|
||||
{
|
||||
try
|
||||
@@ -436,7 +437,7 @@ namespace PepperDash.Essentials
|
||||
if (routeKey.ToLower() != "roomoff")
|
||||
{
|
||||
|
||||
LastSourceKey = routeKey;
|
||||
_lastSourceKey = routeKey;
|
||||
}
|
||||
//else
|
||||
// CurrentSourceInfoKey = null;
|
||||
@@ -521,7 +522,7 @@ namespace PepperDash.Essentials
|
||||
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||
}
|
||||
|
||||
SourceSelectLock.Leave();
|
||||
_sourceSelectLock.Leave();
|
||||
}, 0); // end of CTimer
|
||||
}
|
||||
|
||||
@@ -530,6 +531,8 @@ namespace PepperDash.Essentials
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <param name="sourceItem"></param>
|
||||
/// <param name="sourceItemKey"></param>
|
||||
void DoRouteItem(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
|
||||
{
|
||||
// if there is a $defaultAll on route, run two separate
|
||||
@@ -553,7 +556,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
bool DoRoute(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
|
||||
private bool DoRoute(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
|
||||
{
|
||||
IRoutingSink dest = null;
|
||||
|
||||
@@ -617,9 +620,9 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public override void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||
if (!EnablePowerOnToLastSource || _lastSourceKey == null)
|
||||
return;
|
||||
RunRouteAction(LastSourceKey, SourceListKey);
|
||||
RunRouteAction(_lastSourceKey, SourceListKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -627,10 +630,11 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public static void AllRoomsOff()
|
||||
{
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
var allRooms = DeviceManager.AllDevices.OfType<EssentialsHuddleSpaceRoom>().Where(d => !d.ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as EssentialsHuddleSpaceRoom).SourceListKey);
|
||||
{
|
||||
room.RunRouteAction("roomOff", room.SourceListKey);
|
||||
}
|
||||
}
|
||||
|
||||
#region IPrivacy Members
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
@@ -13,148 +7,21 @@ using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay
|
||||
{
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
var val = CurrentSourceInfo != null
|
||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||
&& disp != null;
|
||||
//&& disp.PowerIsOnFeedback.BoolValue;
|
||||
return val;
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsWarmingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
return disp.IsWarmingUpFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsCoolingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
return disp.IsCoolingDownFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||
public IRoutingSink DefaultAudioDevice { get; private set; }
|
||||
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||
|
||||
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||
|
||||
public string DefaultSourceItem { get; set; }
|
||||
|
||||
public ushort DefaultVolume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If room is off, enables power on to last source. Default true
|
||||
/// </summary>
|
||||
public bool EnablePowerOnToLastSource { get; set; }
|
||||
string LastSourceKey;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IBasicVolumeControls CurrentVolumeControls
|
||||
{
|
||||
get { return _CurrentAudioDevice; }
|
||||
set
|
||||
{
|
||||
if (value == _CurrentAudioDevice) return;
|
||||
|
||||
var oldDev = _CurrentAudioDevice;
|
||||
// derigister this room from the device, if it can
|
||||
if (oldDev is IInUseTracking)
|
||||
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||
var handler = CurrentVolumeDeviceChange;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||
_CurrentAudioDevice = value;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||
// register this room with new device, if it can
|
||||
if (_CurrentAudioDevice is IInUseTracking)
|
||||
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||
}
|
||||
}
|
||||
IBasicVolumeControls _CurrentAudioDevice;
|
||||
|
||||
/// <summary>
|
||||
/// The SourceListItem last run - containing names and icons
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get { return _CurrentSourceInfo; }
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
// remove from in-use tracker, if so equipped
|
||||
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
// add to in-use tracking
|
||||
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||
if (handler != null)
|
||||
handler( _CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
|
||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IRunRouteAction,
|
||||
IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay, IHasCurrentSourceInfoChange
|
||||
{
|
||||
public EssentialsHuddleSpaceRoom(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>
|
||||
(config.Properties.ToString());
|
||||
DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||
PropertiesConfig = config.Properties.ToObject<EssentialsHuddleRoomPropertiesConfig>();
|
||||
DefaultDisplay =
|
||||
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||
//why are we assuming IRoutingSinkWithSwitching here?
|
||||
|
||||
|
||||
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
|
||||
DefaultAudioDevice =
|
||||
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
@@ -164,366 +31,122 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||
{
|
||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||
}
|
||||
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||
{
|
||||
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||
}
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
SourceListKey = String.IsNullOrEmpty(PropertiesConfig.SourceListKey)
|
||||
? "default"
|
||||
: PropertiesConfig.SourceListKey;
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
if (!IsWarmingUpFeedback.BoolValue)
|
||||
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||
};
|
||||
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
};
|
||||
EnablePowerOnToLastSource = true;
|
||||
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SourceListKey = "default";
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
|
||||
IsWarmingFeedbackFunc = () => disp.IsWarmingUpFeedback.BoolValue;
|
||||
|
||||
IsCoolingFeedbackFunc = () => disp.IsCoolingDownFeedback.BoolValue;
|
||||
|
||||
OnFeedbackFunc = () => CurrentSourceInfo != null
|
||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route;
|
||||
|
||||
InitializeDisplay(disp);
|
||||
}
|
||||
|
||||
protected override void IsCoolingDownFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
protected override void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
{
|
||||
var display = sender as DisplayBase;
|
||||
|
||||
if (display == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (display.PowerIsOnFeedback.BoolValue == OnFeedback.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!display.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
CurrentSourceInfo = null;
|
||||
}
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
protected override void IsWarmingUpFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
|
||||
if (IsWarmingUpFeedback.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var displayVolumeControl = DefaultDisplay as IBasicVolumeWithFeedback;
|
||||
|
||||
if (displayVolumeControl == null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
|
||||
"Default display {0} is not volume control control provider", DefaultDisplay.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
displayVolumeControl.SetVolume(DefaultVolume);
|
||||
}
|
||||
|
||||
protected override void CustomSetConfig(DeviceConfig config)
|
||||
{
|
||||
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
|
||||
var newPropertiesConfig =
|
||||
JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
|
||||
|
||||
if (newPropertiesConfig != null)
|
||||
PropertiesConfig = newPropertiesConfig;
|
||||
|
||||
ConfigWriter.UpdateRoomConfig(config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void EndShutdown()
|
||||
{
|
||||
SetDefaultLevels();
|
||||
|
||||
RunDefaultPresentRoute();
|
||||
|
||||
CrestronEnvironment.Sleep(1000);
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
|
||||
|
||||
RunRouteAction("roomOff");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Routes the default source item, if any
|
||||
/// </summary>
|
||||
public override bool RunDefaultPresentRoute()
|
||||
{
|
||||
if (DefaultSourceItem == null)
|
||||
{
|
||||
Debug.Console(0, this, "Unable to run default present route, DefaultSourceItem is null.");
|
||||
return false;
|
||||
PropertiesConfig = newPropertiesConfig;
|
||||
}
|
||||
|
||||
RunRouteAction(DefaultSourceItem);
|
||||
return true;
|
||||
ConfigWriter.UpdateRoomConfig(config);
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
// Add Occupancy object from config
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
{
|
||||
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
}
|
||||
|
||||
this.LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||
SourceListKey = PropertiesConfig.SourceListKey;
|
||||
DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
DefaultVolume = (ushort) (PropertiesConfig.Volumes.Master.Level*65535/100);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
public void RunRouteAction(string routeKey)
|
||||
{
|
||||
RunRouteAction(routeKey, new Action(() => { }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="souceListKey"></param>
|
||||
/// <param name="successCallback"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||
{
|
||||
RunRouteAction(routeKey, new Action(() => { }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="souceListKey"></param>
|
||||
/// <param name="successCallback"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceListKey))
|
||||
{
|
||||
RunRouteAction(routeKey, successCallback);
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||
/// route or commands
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public void RunRouteAction(string routeKey, Action successCallback)
|
||||
{
|
||||
// Run this on a separate thread
|
||||
new CTimer(o =>
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeKey);
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||
if(dict == null)
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to get the list item by it's string key
|
||||
if (!dict.ContainsKey(routeKey))
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||
routeKey, SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = dict[routeKey];
|
||||
//Debug.Console(2, this, "Action {0} has {1} steps",
|
||||
// item.SourceKey, item.RouteList.Count);
|
||||
|
||||
// End usage timer on last source
|
||||
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||
{
|
||||
var lastSource = dict[LastSourceKey].SourceDevice;
|
||||
|
||||
try
|
||||
{
|
||||
if (lastSource != null && lastSource is IUsageTracking)
|
||||
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Let's run it
|
||||
if (routeKey.ToLower() != "roomoff")
|
||||
{
|
||||
LastSourceKey = routeKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSourceInfoKey = null;
|
||||
}
|
||||
|
||||
foreach (var route in item.RouteList)
|
||||
{
|
||||
// if there is a $defaultAll on route, run two separate
|
||||
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Going to assume a single-path route for now
|
||||
var tempVideo = new SourceRouteListItem
|
||||
{
|
||||
DestinationKey = "$defaultDisplay",
|
||||
SourceKey = route.SourceKey,
|
||||
Type = eRoutingSignalType.Video
|
||||
};
|
||||
DoRoute(tempVideo);
|
||||
|
||||
//var tempAudio = new SourceRouteListItem
|
||||
//{
|
||||
// DestinationKey = "$defaultAudio",
|
||||
// SourceKey = route.SourceKey,
|
||||
// Type = eRoutingSignalType.Audio
|
||||
//};
|
||||
//DoRoute(tempAudio);
|
||||
//continue; -- not sure why this was here
|
||||
}
|
||||
else
|
||||
DoRoute(route);
|
||||
}
|
||||
|
||||
// Start usage timer on routed source
|
||||
if (item.SourceDevice is IUsageTracking)
|
||||
{
|
||||
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Set volume control, using default if non provided
|
||||
IBasicVolumeControls volDev = null;
|
||||
// Handle special cases for volume control
|
||||
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||
volDev = DefaultVolumeControls;
|
||||
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||
// Or a specific device, probably rarely used.
|
||||
else
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||
if (dev is IBasicVolumeControls)
|
||||
volDev = dev as IBasicVolumeControls;
|
||||
else if (dev is IHasVolumeDevice)
|
||||
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||
}
|
||||
|
||||
if (volDev != CurrentVolumeControls)
|
||||
{
|
||||
// zero the volume on the device we are leaving.
|
||||
// Set the volume to default on device we are entering
|
||||
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||
{
|
||||
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
|
||||
vd.SetVolume(0);
|
||||
}
|
||||
CurrentVolumeControls = volDev;
|
||||
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||
{
|
||||
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
|
||||
vd.SetVolume(vol);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// store the name and UI info for routes
|
||||
if (item.SourceKey == "$off")
|
||||
{
|
||||
CurrentSourceInfoKey = routeKey;
|
||||
CurrentSourceInfo = null;
|
||||
}
|
||||
else if (item.SourceKey != null)
|
||||
{
|
||||
CurrentSourceInfoKey = routeKey;
|
||||
CurrentSourceInfo = item;
|
||||
}
|
||||
// And finally, set the "control". This will trigger event
|
||||
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
|
||||
|
||||
OnFeedback.FireUpdate();
|
||||
|
||||
// report back when done
|
||||
if (successCallback != null)
|
||||
successCallback();
|
||||
|
||||
}, 0); // end of CTimer
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will power the room on with the last-used source
|
||||
/// </summary>
|
||||
public override void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||
return;
|
||||
RunRouteAction(LastSourceKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does what it says
|
||||
/// </summary>
|
||||
public override void SetDefaultLevels()
|
||||
{
|
||||
Debug.Console(1, this, "Restoring default levels");
|
||||
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
if (vc != null)
|
||||
vc.SetVolume(DefaultVolume);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
bool DoRoute(SourceRouteListItem route)
|
||||
{
|
||||
IRoutingSink dest = null;
|
||||
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultAudioDevice;
|
||||
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultDisplay;
|
||||
else
|
||||
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
|
||||
|
||||
if (dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IPower)
|
||||
(dest as IPower).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||
if (source == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||
return false;
|
||||
}
|
||||
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||
{
|
||||
//Implement this
|
||||
//TODO: Implement RoomVacatedForTimeoutPeriod
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||
/// </summary>
|
||||
public static void AllRoomsOff()
|
||||
{
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
@@ -49,58 +47,7 @@ namespace PepperDash.Essentials
|
||||
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||
|
||||
//************************
|
||||
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
var val = CurrentSourceInfo != null
|
||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||
&& disp != null;
|
||||
//&& disp.PowerIsOnFeedback.BoolValue;
|
||||
return val;
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsWarmingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
return disp.IsWarmingUpFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsCoolingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
return disp.IsCoolingDownFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||
@@ -121,64 +68,36 @@ namespace PepperDash.Essentials
|
||||
/// If room is off, enables power on to last source. Default true
|
||||
/// </summary>
|
||||
public bool EnablePowerOnToLastSource { get; set; }
|
||||
string LastSourceKey;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
|
||||
/// tag to device.
|
||||
/// </summary>
|
||||
public IBasicVolumeControls CurrentVolumeControls
|
||||
{
|
||||
get { return _CurrentAudioDevice; }
|
||||
set
|
||||
{
|
||||
if (value == _CurrentAudioDevice) return;
|
||||
|
||||
var oldDev = _CurrentAudioDevice;
|
||||
// derigister this room from the device, if it can
|
||||
if (oldDev is IInUseTracking)
|
||||
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||
var handler = CurrentVolumeDeviceChange;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||
_CurrentAudioDevice = value;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||
// register this room with new device, if it can
|
||||
if (_CurrentAudioDevice is IInUseTracking)
|
||||
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||
}
|
||||
}
|
||||
IBasicVolumeControls _CurrentAudioDevice;
|
||||
private string _lastSourceKey;
|
||||
|
||||
/// <summary>
|
||||
/// The SourceListItem last run - containing names and icons
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get { return _CurrentSourceInfo; }
|
||||
get { return _currentSourceInfo; }
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
if (value == _currentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
// remove from in-use tracker, if so equipped
|
||||
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||
if(_currentSourceInfo != null && _currentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_currentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
handler(_currentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
_currentSourceInfo = value;
|
||||
|
||||
// add to in-use tracking
|
||||
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||
if (_currentSourceInfo != null && _currentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_currentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
handler(_currentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
private SourceListItem _currentSourceInfo;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
|
||||
@@ -193,7 +112,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||
|
||||
CCriticalSection SourceSelectLock = new CCriticalSection();
|
||||
private readonly CCriticalSection _sourceSelectLock = new CCriticalSection();
|
||||
|
||||
public EssentialsHuddleVtc1Room(DeviceConfig config)
|
||||
: base(config)
|
||||
@@ -205,12 +124,12 @@ namespace PepperDash.Essentials
|
||||
DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||
|
||||
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
||||
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
|
||||
VideoCodecBase;
|
||||
if (VideoCodec == null)
|
||||
throw new ArgumentNullException("codec cannot be null");
|
||||
|
||||
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
||||
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
|
||||
AudioCodecBase;
|
||||
if (AudioCodec == null)
|
||||
Debug.Console(0, this, "No Audio Codec Found");
|
||||
|
||||
@@ -228,8 +147,8 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||
if (DefaultAudioDevice != null)
|
||||
DefaultVolumeControls = DefaultAudioDevice;
|
||||
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
@@ -238,8 +157,8 @@ namespace PepperDash.Essentials
|
||||
// Combines call feedback from both codecs if available
|
||||
InCallFeedback = new BoolFeedback(() =>
|
||||
{
|
||||
bool inAudioCall = false;
|
||||
bool inVideoCall = false;
|
||||
var inAudioCall = false;
|
||||
var inVideoCall = false;
|
||||
|
||||
if (AudioCodec != null)
|
||||
inAudioCall = AudioCodec.IsInCall;
|
||||
@@ -247,72 +166,48 @@ namespace PepperDash.Essentials
|
||||
if (VideoCodec != null)
|
||||
inVideoCall = VideoCodec.IsInCall;
|
||||
|
||||
if (inAudioCall || inVideoCall)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return inAudioCall || inVideoCall;
|
||||
});
|
||||
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (disp.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
};
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
if (!IsWarmingUpFeedback.BoolValue)
|
||||
(CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||
};
|
||||
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback
|
||||
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||
MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
|
||||
|
||||
// Get emergency object, if any
|
||||
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||
Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Emergency Config evaluated.");
|
||||
|
||||
|
||||
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
VideoCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
|
||||
|
||||
if (AudioCodec != null)
|
||||
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
AudioCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
|
||||
|
||||
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
|
||||
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => IsSharingFeedback.FireUpdate();
|
||||
|
||||
// link privacy to VC (for now?)
|
||||
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => PrivacyModeIsOnFeedback.FireUpdate();
|
||||
|
||||
CallTypeFeedback = new IntFeedback(() => 0);
|
||||
|
||||
SourceListKey = "default";
|
||||
EnablePowerOnToLastSource = true;
|
||||
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnFeedbackFunc = () => CurrentSourceInfo != null
|
||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route;
|
||||
|
||||
InitializeDisplay(disp);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -320,6 +215,50 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsRoomBase
|
||||
|
||||
protected override void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
var disp = sender as DisplayBase;
|
||||
|
||||
if (disp == null) return;
|
||||
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (disp.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void IsCoolingDownFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
protected override void IsWarmingUpFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
|
||||
if (IsWarmingUpFeedback.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var basicVolumeWithFeedback = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
if (basicVolumeWithFeedback != null)
|
||||
{
|
||||
basicVolumeWithFeedback.SetVolume(DefaultVolume);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void CustomSetConfig(DeviceConfig config)
|
||||
{
|
||||
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>(config.Properties.ToString());
|
||||
@@ -336,14 +275,14 @@ namespace PepperDash.Essentials
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
|
||||
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
}
|
||||
|
||||
this.LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||
SourceListKey = PropertiesConfig.SourceListKey;
|
||||
DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
@@ -392,9 +331,9 @@ namespace PepperDash.Essentials
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
public void RunRouteAction(string routeKey)
|
||||
public override void RunRouteAction(string routeKey)
|
||||
{
|
||||
RunRouteAction(routeKey, new Action(() => { }));
|
||||
RunRouteAction(routeKey, () => { });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -402,8 +341,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="souceListKey"></param>
|
||||
/// <param name="successCallback"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||
public void RunRouteAction(string routeKey, string souceListKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceListKey))
|
||||
{
|
||||
@@ -429,18 +367,18 @@ namespace PepperDash.Essentials
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||
/// route or commands
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <summary>
|
||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||
/// route or commands
|
||||
/// </summary>
|
||||
public void RunRouteAction(string routeKey, Action successCallback)
|
||||
{
|
||||
// Run this on a separate thread
|
||||
new CTimer(o =>
|
||||
//new CTimer
|
||||
CrestronInvoke.BeginInvoke(o =>
|
||||
{
|
||||
// try to prevent multiple simultaneous selections
|
||||
SourceSelectLock.TryEnter();
|
||||
_sourceSelectLock.TryEnter();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -462,9 +400,9 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
|
||||
// End usage timer on last source
|
||||
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||
if (!string.IsNullOrEmpty(_lastSourceKey))
|
||||
{
|
||||
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
|
||||
var usageLastSource = dict[_lastSourceKey].SourceDevice as IUsageTracking;
|
||||
if (usageLastSource != null && usageLastSource.UsageTracker != null)
|
||||
{
|
||||
try
|
||||
@@ -484,7 +422,7 @@ namespace PepperDash.Essentials
|
||||
if (routeKey.ToLower() != "roomoff")
|
||||
{
|
||||
|
||||
LastSourceKey = routeKey;
|
||||
_lastSourceKey = routeKey;
|
||||
}
|
||||
else
|
||||
CurrentSourceInfoKey = null;
|
||||
@@ -536,7 +474,7 @@ namespace PepperDash.Essentials
|
||||
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||
{
|
||||
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
|
||||
var vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
|
||||
vd.SetVolume(vol);
|
||||
}
|
||||
}
|
||||
@@ -567,7 +505,7 @@ namespace PepperDash.Essentials
|
||||
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||
}
|
||||
|
||||
SourceSelectLock.Leave();
|
||||
_sourceSelectLock.Leave();
|
||||
}, 0); // end of CTimer
|
||||
}
|
||||
|
||||
@@ -598,9 +536,9 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
bool DoRoute(SourceRouteListItem route)
|
||||
private bool DoRoute(SourceRouteListItem route)
|
||||
{
|
||||
IRoutingSink dest = null;
|
||||
IRoutingSink dest;
|
||||
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
|
||||
@@ -654,9 +592,9 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public override void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||
if (!EnablePowerOnToLastSource || _lastSourceKey == null)
|
||||
return;
|
||||
RunRouteAction(LastSourceKey);
|
||||
RunRouteAction(_lastSourceKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -667,7 +605,13 @@ namespace PepperDash.Essentials
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||
{
|
||||
var essentialsHuddleSpaceRoom = room as EssentialsHuddleSpaceRoom;
|
||||
if (essentialsHuddleSpaceRoom != null)
|
||||
{
|
||||
essentialsHuddleSpaceRoom.RunRouteAction("roomOff");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IPrivacy Members
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using PepperDash.Core;
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
@@ -23,7 +13,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
public Dictionary<eSourceListItemDestinationTypes, IRoutingSinkWithSwitching> Displays { get; protected set;}
|
||||
|
||||
public EssentialsNDisplayRoomBase(DeviceConfig config)
|
||||
protected EssentialsNDisplayRoomBase(DeviceConfig config)
|
||||
: base (config)
|
||||
{
|
||||
Displays = new Dictionary<eSourceListItemDestinationTypes, IRoutingSinkWithSwitching>();
|
||||
|
||||
@@ -11,6 +11,7 @@ using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.PageManagers;
|
||||
using PepperDashEssentials.UIDrivers.EssentialsDualDisplay;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
@@ -178,7 +179,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
void Panel_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
|
||||
void Panel_SigChange(object currentDevice, SigEventArgs args)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Sig change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||
@@ -231,8 +232,10 @@ namespace PepperDash.Essentials
|
||||
|
||||
// AV Driver
|
||||
Debug.Console(0, panelController, "Adding huddle space AV driver");
|
||||
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props);
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props)
|
||||
{
|
||||
DefaultRoomKey = props.DefaultRoomKey
|
||||
};
|
||||
mainDriver.AvDriver = avDriver;
|
||||
avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom;
|
||||
|
||||
@@ -249,24 +252,75 @@ namespace PepperDash.Essentials
|
||||
|
||||
panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted.
|
||||
|
||||
if (panelController.Panel is TswFt5ButtonSystem)
|
||||
if (!(panelController.Panel is TswFt5ButtonSystem))
|
||||
{
|
||||
var tsw = panelController.Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
if (mainDriver.EnvironmentDriver != null)
|
||||
tsw.Lights.UserObject = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
//mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin);
|
||||
mainDriver.EnvironmentDriver.Toggle();
|
||||
}
|
||||
});
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
return;
|
||||
}
|
||||
var tsw = panelController.Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
if (mainDriver.EnvironmentDriver != null)
|
||||
tsw.Lights.UserObject = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
//mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin);
|
||||
mainDriver.EnvironmentDriver.Toggle();
|
||||
}
|
||||
});
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
}
|
||||
else if (room is EssentialsDualDisplayRoom)
|
||||
{
|
||||
Debug.Console(0, panelController, "Adding Dual Display VTC AV driver");
|
||||
|
||||
// Header Driver
|
||||
mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props);
|
||||
|
||||
// AV Driver
|
||||
var avDriver = new EssentialsDualDisplayPanelAvFunctionsDriver(mainDriver, props);
|
||||
|
||||
var codecDriver = new UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver,
|
||||
(room as EssentialsDualDisplayRoom).VideoCodec, mainDriver.HeaderDriver);
|
||||
avDriver.SetVideoCodecDriver(codecDriver);
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
avDriver.CurrentRoom = room as EssentialsDualDisplayRoom;
|
||||
|
||||
// Environment Driver
|
||||
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
|
||||
{
|
||||
Debug.Console(0, panelController, "Adding environment driver");
|
||||
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props);
|
||||
|
||||
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment);
|
||||
}
|
||||
|
||||
mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom);
|
||||
|
||||
panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted.
|
||||
|
||||
if (!(panelController.Panel is TswFt5ButtonSystem))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var tsw = panelController.Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.EndMeetingPress(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
if (mainDriver.EnvironmentDriver != null)
|
||||
tsw.Lights.UserObject = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
//mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin);
|
||||
mainDriver.EnvironmentDriver.Toggle();
|
||||
}
|
||||
});
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
}
|
||||
else if (room is EssentialsHuddleVtc1Room)
|
||||
{
|
||||
@@ -278,7 +332,7 @@ namespace PepperDash.Essentials
|
||||
// AV Driver
|
||||
var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props);
|
||||
|
||||
var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver,
|
||||
var codecDriver = new UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver,
|
||||
(room as EssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver);
|
||||
avDriver.SetVideoCodecDriver(codecDriver);
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
@@ -298,24 +352,25 @@ namespace PepperDash.Essentials
|
||||
|
||||
panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted.
|
||||
|
||||
if (panelController.Panel is TswFt5ButtonSystem)
|
||||
if (!(panelController.Panel is TswFt5ButtonSystem))
|
||||
{
|
||||
var tsw = panelController.Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.EndMeetingPress(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
if (mainDriver.EnvironmentDriver != null)
|
||||
tsw.Lights.UserObject = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
//mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin);
|
||||
mainDriver.EnvironmentDriver.Toggle();
|
||||
}
|
||||
});
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
return;
|
||||
}
|
||||
var tsw = panelController.Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.EndMeetingPress(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
if (mainDriver.EnvironmentDriver != null)
|
||||
tsw.Lights.UserObject = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
//mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin);
|
||||
mainDriver.EnvironmentDriver.Toggle();
|
||||
}
|
||||
});
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,231 +1,24 @@
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using Crestron.SimplSharp;
|
||||
//using Crestron.SimplSharpPro;
|
||||
//using Crestron.SimplSharpPro.DeviceSupport;
|
||||
//using PepperDash.Core;
|
||||
//using PepperDash.Essentials.Core;
|
||||
//using PepperDash.Essentials.Core.SmartObjects;
|
||||
//using PepperDash.Essentials.Core.PageManagers;
|
||||
using System;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDashEssentials.UIDrivers.EssentialsDualDisplay;
|
||||
|
||||
//namespace PepperDash.Essentials
|
||||
//{
|
||||
// public class DualDisplaySimpleOrAdvancedRouting : PanelDriverBase
|
||||
// {
|
||||
// EssentialsPresentationPanelAvFunctionsDriver Parent;
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class DualDisplaySimpleOrAdvancedRouting : PanelDriverBase
|
||||
{
|
||||
private readonly EssentialsDualDisplayPanelAvFunctionsDriver _parent;
|
||||
private EssentialsDualDisplayRoom _currentRoom;
|
||||
|
||||
// /// <summary>
|
||||
// /// Smart Object 3200
|
||||
// /// </summary>
|
||||
// SubpageReferenceList SourcesSrl;
|
||||
private SourceListItem PendingSource;
|
||||
|
||||
public DualDisplaySimpleOrAdvancedRouting(EssentialsDualDisplayPanelAvFunctionsDriver parent)
|
||||
: base(parent.TriList)
|
||||
{
|
||||
_parent = parent;
|
||||
_currentRoom = _parent.CurrentRoom as EssentialsDualDisplayRoom;
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// For tracking feedback on last selected
|
||||
// /// </summary>
|
||||
// BoolInputSig LastSelectedSourceSig;
|
||||
|
||||
// /// <summary>
|
||||
// /// The source that has been selected and is awaiting assignment to a display
|
||||
// /// </summary>
|
||||
// SourceListItem PendingSource;
|
||||
|
||||
// bool IsSharingModeAdvanced;
|
||||
|
||||
// public DualDisplaySimpleOrAdvancedRouting(EssentialsPresentationPanelAvFunctionsDriver parent) : base(parent.TriList)
|
||||
// {
|
||||
// Parent = parent;
|
||||
// SourcesSrl = new SubpageReferenceList(TriList, 3200, 3, 3, 3);
|
||||
|
||||
// TriList.SetSigFalseAction(UIBoolJoin.ToggleSharingModePress, ToggleSharingModePressed);
|
||||
|
||||
// TriList.SetSigFalseAction(UIBoolJoin.Display1AudioButtonPressAndFb, Display1AudioPress);
|
||||
// TriList.SetSigFalseAction(UIBoolJoin.Display1ControlButtonPress, Display1ControlPress);
|
||||
// TriList.SetSigTrueAction(UIBoolJoin.Display1SelectPressAndFb, Display1Press);
|
||||
|
||||
// TriList.SetSigFalseAction(UIBoolJoin.Display2AudioButtonPressAndFb, Display2AudioPress);
|
||||
// TriList.SetSigFalseAction(UIBoolJoin.Display2ControlButtonPress, Display2ControlPress);
|
||||
// TriList.SetSigTrueAction(UIBoolJoin.Display2SelectPressAndFb, Display2Press);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// ///
|
||||
// /// </summary>
|
||||
// public override void Show()
|
||||
// {
|
||||
// TriList.BooleanInput[UIBoolJoin.ToggleSharingModeVisible].BoolValue = true;
|
||||
// TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = true;
|
||||
// if(IsSharingModeAdvanced)
|
||||
// TriList.BooleanInput[UIBoolJoin.DualDisplayPageVisible].BoolValue = true;
|
||||
// else
|
||||
// TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
|
||||
// base.Show();
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// ///
|
||||
// /// </summary>
|
||||
// //public override void Hide()
|
||||
// //{
|
||||
// // TriList.BooleanInput[UIBoolJoin.ToggleSharingModeVisible].BoolValue = false;
|
||||
// // TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = false;
|
||||
// // if(IsSharingModeAdvanced)
|
||||
// // TriList.BooleanInput[UIBoolJoin.DualDisplayPageVisible].BoolValue = false;
|
||||
// // else
|
||||
// // TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
// // base.Hide();
|
||||
// //}
|
||||
|
||||
// public void SetCurrentRoomFromParent()
|
||||
// {
|
||||
// if (IsSharingModeAdvanced)
|
||||
// return; // add stuff here
|
||||
// else
|
||||
// SetupSourceListForSimpleRouting();
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// ///
|
||||
// /// </summary>
|
||||
// void SetupSourceListForSimpleRouting()
|
||||
// {
|
||||
// // get the source list config and set up the source list
|
||||
// var config = ConfigReader.ConfigObject.SourceLists;
|
||||
// if (config.ContainsKey(Parent.CurrentRoom.SourceListKey))
|
||||
// {
|
||||
// var srcList = config[Parent.CurrentRoom.SourceListKey]
|
||||
// .Values.ToList().OrderBy(s => s.Order);
|
||||
// // Setup sources list
|
||||
// uint i = 1; // counter for UI list
|
||||
// foreach (var srcConfig in srcList)
|
||||
// {
|
||||
// if (!srcConfig.IncludeInSourceList) // Skip sources marked this way
|
||||
// continue;
|
||||
|
||||
// var sourceKey = srcConfig.SourceKey;
|
||||
// var actualSource = DeviceManager.GetDeviceForKey(sourceKey) as Device;
|
||||
// if (actualSource == null)
|
||||
// {
|
||||
// Debug.Console(0, "Cannot assign missing source '{0}' to source UI list",
|
||||
// srcConfig.SourceKey);
|
||||
// continue;
|
||||
// }
|
||||
// var localSrcItem = srcConfig; // lambda scope below
|
||||
// var localIndex = i;
|
||||
// SourcesSrl.GetBoolFeedbackSig(i, 1).UserObject = new Action<bool>(b =>
|
||||
// {
|
||||
// if (IsSharingModeAdvanced)
|
||||
// {
|
||||
// if (LastSelectedSourceSig != null)
|
||||
// LastSelectedSourceSig.BoolValue = false;
|
||||
// SourceListButtonPress(localSrcItem);
|
||||
// LastSelectedSourceSig = SourcesSrl.BoolInputSig(localIndex, 1);
|
||||
// LastSelectedSourceSig.BoolValue = true;
|
||||
// }
|
||||
// else
|
||||
// Parent.CurrentRoom.DoSourceToAllDestinationsRoute(localSrcItem);
|
||||
// });
|
||||
// SourcesSrl.StringInputSig(i, 1).StringValue = srcConfig.PreferredName;
|
||||
// i++;
|
||||
|
||||
// //var item = new SubpageReferenceListSourceItem(i++, SourcesSrl, srcConfig,
|
||||
// // b => { if (!b) UiSelectSource(localSrcConfig); });
|
||||
// //SourcesSrl.AddItem(item); // add to the SRL
|
||||
// //item.RegisterForSourceChange(Parent.CurrentRoom);
|
||||
// }
|
||||
// SourcesSrl.Count = (ushort)(i - 1);
|
||||
// Parent.CurrentRoom.CurrentSingleSourceChange += CurrentRoom_CurrentSourceInfoChange;
|
||||
// Parent.CurrentRoom.CurrentDisplay1SourceChange += CurrentRoom_CurrentDisplay1SourceChange;
|
||||
// Parent.CurrentRoom.CurrentDisplay2SourceChange += CurrentRoom_CurrentDisplay2SourceChange;
|
||||
// }
|
||||
// }
|
||||
|
||||
// void SetupSourceListForAdvancedRouting()
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// void CurrentRoom_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// void CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
||||
// {
|
||||
// TriList.StringInput[UIStringJoin.Display1SourceLabel].StringValue = PendingSource.PreferredName;
|
||||
|
||||
// }
|
||||
|
||||
// void CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
||||
// {
|
||||
// TriList.StringInput[UIStringJoin.Display2SourceLabel].StringValue = PendingSource.PreferredName;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// ///
|
||||
// /// </summary>
|
||||
// void ToggleSharingModePressed()
|
||||
// {
|
||||
// Hide();
|
||||
// IsSharingModeAdvanced = !IsSharingModeAdvanced;
|
||||
// TriList.BooleanInput[UIBoolJoin.ToggleSharingModePress].BoolValue = IsSharingModeAdvanced;
|
||||
// Show();
|
||||
// }
|
||||
|
||||
// public void SourceListButtonPress(SourceListItem item)
|
||||
// {
|
||||
// // start the timer
|
||||
// // show FB on potential source
|
||||
// TriList.BooleanInput[UIBoolJoin.Display1AudioButtonEnable].BoolValue = false;
|
||||
// TriList.BooleanInput[UIBoolJoin.Display1ControlButtonEnable].BoolValue = false;
|
||||
// TriList.BooleanInput[UIBoolJoin.Display2AudioButtonEnable].BoolValue = false;
|
||||
// TriList.BooleanInput[UIBoolJoin.Display2ControlButtonEnable].BoolValue = false;
|
||||
// PendingSource = item;
|
||||
// }
|
||||
|
||||
// void EnableAppropriateDisplayButtons()
|
||||
// {
|
||||
// TriList.BooleanInput[UIBoolJoin.Display1AudioButtonEnable].BoolValue = true;
|
||||
// TriList.BooleanInput[UIBoolJoin.Display1ControlButtonEnable].BoolValue = true;
|
||||
// TriList.BooleanInput[UIBoolJoin.Display2AudioButtonEnable].BoolValue = true;
|
||||
// TriList.BooleanInput[UIBoolJoin.Display2ControlButtonEnable].BoolValue = true;
|
||||
// if (LastSelectedSourceSig != null)
|
||||
// LastSelectedSourceSig.BoolValue = false;
|
||||
// }
|
||||
|
||||
// public void Display1Press()
|
||||
// {
|
||||
// EnableAppropriateDisplayButtons();
|
||||
// Parent.CurrentRoom.SourceToDisplay1(PendingSource);
|
||||
// // Enable end meeting
|
||||
// }
|
||||
|
||||
// public void Display1AudioPress()
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// public void Display1ControlPress()
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// public void Display2Press()
|
||||
// {
|
||||
// EnableAppropriateDisplayButtons();
|
||||
// Parent.CurrentRoom.SourceToDisplay2(PendingSource);
|
||||
// }
|
||||
|
||||
// public void Display2AudioPress()
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// public void Display2ControlPress()
|
||||
// {
|
||||
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// Reads the device keys from the config and gets the devices by key
|
||||
/// </summary>
|
||||
public void GetDevicesFromConfig(Room.Config.EssentialsEnvironmentPropertiesConfig EnvironmentPropertiesConfig)
|
||||
public void GetDevicesFromConfig(Core.Rooms.Config.EssentialsEnvironmentPropertiesConfig EnvironmentPropertiesConfig)
|
||||
{
|
||||
if (EnvironmentPropertiesConfig != null)
|
||||
{
|
||||
|
||||
@@ -10,11 +10,13 @@ using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Devices.VideoCodec;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.PageManagers;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDashEssentials.UIDrivers.EssentialsDualDisplay;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
@@ -135,37 +137,39 @@ namespace PepperDash.Essentials
|
||||
return nextJoin;
|
||||
}
|
||||
|
||||
uint SetUpCalendarButton(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, uint nextJoin)
|
||||
uint SetUpCalendarButton(IHasCalendarButton avDriver, uint nextJoin)
|
||||
{
|
||||
// Calendar button
|
||||
if (avDriver.CurrentRoom.ScheduleSource != null)
|
||||
var room = avDriver.CurrentRoom as EssentialsHuddleVtc1Room;
|
||||
if (room != null && room.ScheduleSource == null)
|
||||
{
|
||||
var tempJoin = nextJoin;
|
||||
TriList.SetString(tempJoin, "Calendar");
|
||||
CalendarCaretVisible = tempJoin + 10;
|
||||
TriList.SetSigFalseAction(tempJoin, () =>
|
||||
{
|
||||
avDriver.CalendarPress();
|
||||
CaretInterlock.ShowInterlocked(CalendarCaretVisible);
|
||||
});
|
||||
|
||||
nextJoin--;
|
||||
return nextJoin;
|
||||
}
|
||||
else
|
||||
return nextJoin;
|
||||
|
||||
var tempJoin = nextJoin;
|
||||
TriList.SetString(tempJoin, "Calendar");
|
||||
CalendarCaretVisible = tempJoin + 10;
|
||||
TriList.SetSigFalseAction(tempJoin, () =>
|
||||
{
|
||||
avDriver.CalendarPress();
|
||||
CaretInterlock.ShowInterlocked(CalendarCaretVisible);
|
||||
});
|
||||
|
||||
nextJoin--;
|
||||
return nextJoin;
|
||||
}
|
||||
|
||||
uint SetUpCallButton(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, uint nextJoin)
|
||||
uint SetUpCallButton(IHasCallButton avDriver, uint nextJoin)
|
||||
{
|
||||
// Call button
|
||||
var room = avDriver.CurrentRoom as EssentialsHuddleVtc1Room;
|
||||
var tempJoin = nextJoin;
|
||||
TriList.SetString(tempJoin, "DND");
|
||||
CallCaretVisible = tempJoin + 10;
|
||||
TriList.SetSigFalseAction(tempJoin, () =>
|
||||
{
|
||||
avDriver.ShowActiveCallsList();
|
||||
if(avDriver.CurrentRoom.InCallFeedback.BoolValue)
|
||||
if(room != null && room.InCallFeedback.BoolValue)
|
||||
CaretInterlock.ShowInterlocked(CallCaretVisible);
|
||||
});
|
||||
HeaderCallButtonIconSig = TriList.StringInput[tempJoin];
|
||||
@@ -224,6 +228,7 @@ namespace PepperDash.Essentials
|
||||
public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, EssentialsHuddleVtc1Room currentRoom)
|
||||
{
|
||||
HeaderButtonsAreSetUp = false;
|
||||
var room = avDriver.CurrentRoom as EssentialsHuddleVtc1Room;
|
||||
|
||||
TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true);
|
||||
|
||||
@@ -256,7 +261,67 @@ namespace PepperDash.Essentials
|
||||
() =>
|
||||
{
|
||||
avDriver.ShowActiveCallsList();
|
||||
if (avDriver.CurrentRoom.InCallFeedback.BoolValue)
|
||||
if (room != null && room.InCallFeedback.BoolValue)
|
||||
CaretInterlock.ShowInterlocked(CallCaretVisible);
|
||||
});
|
||||
|
||||
// Set Call Status Subpage Position
|
||||
|
||||
if (nextJoin == 3951)
|
||||
{
|
||||
// Set to right position
|
||||
TriList.SetBool(UIBoolJoin.HeaderCallStatusLeftPositionVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.HeaderCallStatusRightPositionVisible, true);
|
||||
}
|
||||
else if (nextJoin == 3950)
|
||||
{
|
||||
// Set to left position
|
||||
TriList.SetBool(UIBoolJoin.HeaderCallStatusLeftPositionVisible, true);
|
||||
TriList.SetBool(UIBoolJoin.HeaderCallStatusRightPositionVisible, false);
|
||||
}
|
||||
|
||||
HeaderButtonsAreSetUp = true;
|
||||
|
||||
ComputeHeaderCallStatus(currentRoom.VideoCodec);
|
||||
}
|
||||
|
||||
public void SetupHeaderButtons(EssentialsDualDisplayPanelAvFunctionsDriver avDriver, EssentialsHuddleVtc1Room currentRoom)
|
||||
{
|
||||
HeaderButtonsAreSetUp = false;
|
||||
var room = avDriver.CurrentRoom as EssentialsHuddleVtc1Room;
|
||||
|
||||
TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true);
|
||||
|
||||
var roomConf = currentRoom.PropertiesConfig;
|
||||
|
||||
// Register for the PopupInterlock IsShowsFeedback event to tie the header carets subpage visiblity to it
|
||||
Parent.AvDriver.PopupInterlock.StatusChanged -= PopupInterlock_StatusChanged;
|
||||
Parent.AvDriver.PopupInterlock.StatusChanged += PopupInterlock_StatusChanged;
|
||||
|
||||
SetUpGear(avDriver, currentRoom);
|
||||
|
||||
SetUpHelpButton(roomConf);
|
||||
|
||||
uint nextJoin = 3953;
|
||||
|
||||
nextJoin = SetUpEnvironmentButton(Parent.EnvironmentDriver, nextJoin);
|
||||
|
||||
nextJoin = SetUpCalendarButton(avDriver, nextJoin);
|
||||
|
||||
nextJoin = SetUpCallButton(avDriver, nextJoin);
|
||||
|
||||
// blank any that remain
|
||||
for (var i = nextJoin; i > 3950; i--)
|
||||
{
|
||||
TriList.SetString(i, "Blank");
|
||||
TriList.SetSigFalseAction(i, () => { });
|
||||
}
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.HeaderCallStatusLabelPress,
|
||||
() =>
|
||||
{
|
||||
avDriver.ShowActiveCallsList();
|
||||
if (room != null && room.InCallFeedback.BoolValue)
|
||||
CaretInterlock.ShowInterlocked(CallCaretVisible);
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharpPro;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
|
||||
namespace PepperDashEssentials.UIDrivers.EssentialsDualDisplay
|
||||
{
|
||||
public class EssentialsDualDisplayPanelAvFunctionsDriver : EssentialsHuddleVtc1PanelAvFunctionsDriver
|
||||
{
|
||||
private EssentialsDualDisplayRoom _currentRoom;
|
||||
|
||||
private readonly BoolInputSig _routeToggleVisibility;
|
||||
private readonly BoolInputSig _dualDisplayControlVisibility;
|
||||
|
||||
private readonly BoolOutputSig _sharingModeSig;
|
||||
|
||||
private readonly BoolFeedback _sharingModeFeedback;
|
||||
private readonly BoolFeedback _dualDisplayVisiblityFeedback;
|
||||
private readonly BoolFeedback _routeToggleVisiblityFeedback;
|
||||
|
||||
public EssentialsDualDisplayPanelAvFunctionsDriver(PanelDriverBase parent, CrestronTouchpanelPropertiesConfig config) : base(parent, config)
|
||||
{
|
||||
_routeToggleVisibility = parent.TriList.BooleanInput[UIBoolJoin.ToggleSharingModeVisible];
|
||||
_dualDisplayControlVisibility = parent.TriList.BooleanInput[UIBoolJoin.DualDisplayPageVisible];
|
||||
_sharingModeSig = parent.TriList.BooleanOutput[UIBoolJoin.ToggleSharingModePress];
|
||||
|
||||
_sharingModeSig.SetBoolSigAction(ToggleVideoBehavior);
|
||||
|
||||
_sharingModeFeedback = new BoolFeedback(() => _currentRoom.VideoRoutingBehavior == EVideoBehavior.Advanced);
|
||||
_sharingModeFeedback.LinkInputSig(parent.TriList.BooleanInput[UIBoolJoin.ToggleSharingModePress]);
|
||||
|
||||
_dualDisplayVisiblityFeedback =
|
||||
new BoolFeedback(
|
||||
() =>
|
||||
_currentRoom.VideoRoutingBehavior == EVideoBehavior.Advanced &&
|
||||
CurrentMode == UiDisplayMode.Presentation);
|
||||
_dualDisplayVisiblityFeedback.LinkInputSig(_dualDisplayControlVisibility);
|
||||
|
||||
_routeToggleVisiblityFeedback =
|
||||
new BoolFeedback(
|
||||
() => _currentRoom.RoomConfig.EnableVideoBehaviorToggle && CurrentMode == UiDisplayMode.Presentation);
|
||||
_routeToggleVisiblityFeedback.LinkInputSig(_routeToggleVisibility);
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsHuddleVtc1PanelAvFunctionsDriver
|
||||
|
||||
protected override void ShowCurrentSource()
|
||||
{
|
||||
if (_currentRoom.VideoRoutingBehavior == EVideoBehavior.Advanced) return;
|
||||
|
||||
base.ShowCurrentSource();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ToggleVideoBehavior(bool value)
|
||||
{
|
||||
if (!value) return;
|
||||
|
||||
_currentRoom.VideoRoutingBehavior = _currentRoom.VideoRoutingBehavior == EVideoBehavior.Basic
|
||||
? EVideoBehavior.Advanced
|
||||
: EVideoBehavior.Basic;
|
||||
|
||||
_sharingModeFeedback.FireUpdate();
|
||||
_dualDisplayVisiblityFeedback.FireUpdate();
|
||||
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, _currentRoom.VideoRoutingBehavior == EVideoBehavior.Basic);
|
||||
|
||||
if (_currentRoom.VideoRoutingBehavior == EVideoBehavior.Advanced)
|
||||
{
|
||||
CurrentSourcePageManager.Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_currentRoom.CurrentSourceInfo != null)
|
||||
{
|
||||
UiSelectSource(_currentRoom.CurrentSourceInfoKey);
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
}
|
||||
CurrentSourcePageManager.Show();
|
||||
}
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsHuddleVtc1PanelAvFunctionsDriver
|
||||
|
||||
#region Overrides of EssentialsHuddleVtc1PanelAvFunctionsDriver
|
||||
|
||||
protected override void SetCurrentRoom(EssentialsHuddleVtc1Room room)
|
||||
{
|
||||
_currentRoom = room as EssentialsDualDisplayRoom;
|
||||
|
||||
base.SetCurrentRoom(room);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides of EssentialsHuddleVtc1PanelAvFunctionsDriver
|
||||
|
||||
protected override void ActivityShareButtonPressed()
|
||||
{
|
||||
base.ActivityShareButtonPressed();
|
||||
|
||||
_dualDisplayVisiblityFeedback.FireUpdate();
|
||||
_routeToggleVisiblityFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsHuddleVtc1PanelAvFunctionsDriver
|
||||
|
||||
public override void ActivityCallButtonPressed()
|
||||
{
|
||||
base.ActivityCallButtonPressed();
|
||||
|
||||
_dualDisplayVisiblityFeedback.FireUpdate();
|
||||
_routeToggleVisiblityFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void SetupSourceList()
|
||||
{
|
||||
var inCall = _currentRoom.InCallFeedback.BoolValue;
|
||||
var sourceLists = ConfigReader.ConfigObject.SourceLists;
|
||||
if (!sourceLists.ContainsKey(_currentRoom.SourceListKey))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sourceList = sourceLists[_currentRoom.SourceListKey].OrderBy(kv => kv.Value.Order);
|
||||
|
||||
SourceStagingSrl.Clear();
|
||||
uint i = 1;
|
||||
foreach (var src in sourceList)
|
||||
{
|
||||
var source = src.Value;
|
||||
var sourceKey = src.Key;
|
||||
Debug.Console(1, "**** {0}, {1}, {2}, {3}, {4}", source.PreferredName, source.IncludeInSourceList,
|
||||
source.DisableCodecSharing, inCall, CurrentMode);
|
||||
|
||||
if (!source.IncludeInSourceList || (inCall && source.DisableCodecSharing)
|
||||
|| CurrentMode == UiDisplayMode.Call && source.DisableCodecSharing)
|
||||
{
|
||||
Debug.Console(1, "Skipping {0}", source.PreferredName);
|
||||
continue;
|
||||
}
|
||||
var srlItem = new SubpageReferenceListSourceItem(i++, SourceStagingSrl, source,
|
||||
b => { if (!b) UiSelectSource(sourceKey); });
|
||||
|
||||
SourceStagingSrl.AddItem(srlItem);
|
||||
srlItem.RegisterForSourceChange(_currentRoom);
|
||||
}
|
||||
SourceStagingSrl.Count = (ushort) (i - 1);
|
||||
Debug.Console(2, "Dual Display Source Count: {0}", SourceStagingSrl.Count);
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsHuddleVtc1PanelAvFunctionsDriver
|
||||
|
||||
protected override void SetSourceFeedback()
|
||||
{
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
// If there's no default, show UI elements
|
||||
if (!CurrentRoom.RunDefaultPresentRoute() && _currentRoom.VideoRoutingBehavior == EVideoBehavior.Basic)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
}
|
||||
}
|
||||
else // room is on show what's active or select a source if nothing is yet active
|
||||
{
|
||||
if (CurrentRoom.CurrentSourceInfo == null ||
|
||||
CurrentRoom.CurrentSourceInfoKey == EssentialsHuddleVtc1Room.DefaultCodecRouteString)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CurrentSourcePageManager == null) return;
|
||||
|
||||
if (_currentRoom.VideoRoutingBehavior == EVideoBehavior.Advanced)
|
||||
{
|
||||
CurrentSourcePageManager.Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentSourcePageManager.Show();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void RefreshRoom(EssentialsDualDisplayRoom room)
|
||||
{
|
||||
RefreshCurrentRoom(room);
|
||||
|
||||
_currentRoom = room;
|
||||
|
||||
_routeToggleVisibility.BoolValue = _currentRoom.RoomConfig.EnableVideoBehaviorToggle;
|
||||
_sharingModeFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
private void UiSelectSource(string sourceKey)
|
||||
{
|
||||
if (_currentRoom.VideoRoutingBehavior == EVideoBehavior.Advanced)
|
||||
{
|
||||
_currentRoom.SelectSource(sourceKey, _currentRoom.SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
_currentRoom.RunRouteAction(sourceKey);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -2,22 +2,17 @@
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.PageManagers;
|
||||
using PepperDash.Essentials.UIDrivers;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsHuddlePanelAvFunctionsDriver : PanelDriverBase, IAVDriver
|
||||
{
|
||||
CrestronTouchpanelPropertiesConfig Config;
|
||||
private readonly CrestronTouchpanelPropertiesConfig _config;
|
||||
|
||||
public enum UiDisplayMode
|
||||
{
|
||||
@@ -35,8 +30,8 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public uint VolumeButtonPopupTimeout
|
||||
{
|
||||
get { return VolumeButtonsPopupFeedback.TimeoutMs; }
|
||||
set { VolumeButtonsPopupFeedback.TimeoutMs = value; }
|
||||
get { return _volumeButtonsPopupFeedback.TimeoutMs; }
|
||||
set { _volumeButtonsPopupFeedback.TimeoutMs = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -44,8 +39,8 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public uint VolumeGaugePopupTimeout
|
||||
{
|
||||
get { return VolumeGaugeFeedback.TimeoutMs; }
|
||||
set { VolumeGaugeFeedback.TimeoutMs = value; }
|
||||
get { return _volumeGaugeFeedback.TimeoutMs; }
|
||||
set { _volumeGaugeFeedback.TimeoutMs = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -53,21 +48,12 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public uint PowerOffTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DefaultRoomKey
|
||||
{
|
||||
get { return _DefaultRoomKey; }
|
||||
set
|
||||
{
|
||||
_DefaultRoomKey = value;
|
||||
//CurrentRoom = DeviceManager.GetDeviceForKey(value) as EssentialsHuddleSpaceRoom;
|
||||
}
|
||||
}
|
||||
string _DefaultRoomKey;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DefaultRoomKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Indicates that the SetHeaderButtons method has completed successfully
|
||||
/// </summary>
|
||||
public bool HeaderButtonsAreSetUp { get; private set; }
|
||||
@@ -77,13 +63,13 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public EssentialsHuddleSpaceRoom CurrentRoom
|
||||
{
|
||||
get { return _CurrentRoom; }
|
||||
get { return _currentRoom; }
|
||||
set
|
||||
{
|
||||
SetCurrentRoom(value);
|
||||
}
|
||||
}
|
||||
EssentialsHuddleSpaceRoom _CurrentRoom;
|
||||
EssentialsHuddleSpaceRoom _currentRoom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -93,88 +79,86 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// For hitting feedback
|
||||
/// </summary>
|
||||
BoolInputSig ShareButtonSig;
|
||||
BoolInputSig EndMeetingButtonSig;
|
||||
private readonly BoolInputSig _shareButtonSig;
|
||||
private BoolInputSig _endMeetingButtonSig;
|
||||
|
||||
/// <summary>
|
||||
/// Controls the extended period that the volume gauge shows on-screen,
|
||||
/// as triggered by Volume up/down operations
|
||||
/// </summary>
|
||||
BoolFeedbackPulseExtender VolumeGaugeFeedback;
|
||||
private readonly BoolFeedbackPulseExtender _volumeGaugeFeedback;
|
||||
|
||||
/// <summary>
|
||||
/// Controls the period that the volume buttons show on non-hard-button
|
||||
/// interfaces
|
||||
/// </summary>
|
||||
BoolFeedbackPulseExtender VolumeButtonsPopupFeedback;
|
||||
private readonly BoolFeedbackPulseExtender _volumeButtonsPopupFeedback;
|
||||
|
||||
/// <summary>
|
||||
/// The parent driver for this
|
||||
/// </summary>
|
||||
PanelDriverBase Parent;
|
||||
private readonly PanelDriverBase _parent;
|
||||
|
||||
/// <summary>
|
||||
/// All children attached to this driver. For hiding and showing as a group.
|
||||
/// </summary>
|
||||
List<PanelDriverBase> ChildDrivers = new List<PanelDriverBase>();
|
||||
private List<PanelDriverBase> _childDrivers = new List<PanelDriverBase>();
|
||||
|
||||
List<BoolInputSig> CurrentDisplayModeSigsInUse = new List<BoolInputSig>();
|
||||
private readonly List<BoolInputSig> _currentDisplayModeSigsInUse = new List<BoolInputSig>();
|
||||
|
||||
//// Important smart objects
|
||||
|
||||
/// <summary>
|
||||
/// Smart Object 3200
|
||||
/// </summary>
|
||||
SubpageReferenceList SourcesSrl;
|
||||
private readonly SubpageReferenceList _sourcesSrl;
|
||||
|
||||
/// <summary>
|
||||
/// Smart Object 15022
|
||||
/// </summary>
|
||||
SubpageReferenceList ActivityFooterSrl;
|
||||
private readonly SubpageReferenceList _activityFooterSrl;
|
||||
|
||||
/// <summary>
|
||||
/// Tracks which audio page group the UI is in
|
||||
/// </summary>
|
||||
UiDisplayMode CurrentDisplayMode;
|
||||
private UiDisplayMode _currentDisplayMode;
|
||||
|
||||
/// <summary>
|
||||
/// The AV page mangagers that have been used, to keep them alive for later
|
||||
/// </summary>
|
||||
Dictionary<object, PageManager> PageManagers = new Dictionary<object, PageManager>();
|
||||
private readonly Dictionary<object, PageManager> _pageManagers = new Dictionary<object, PageManager>();
|
||||
|
||||
/// <summary>
|
||||
/// Current page manager running for a source
|
||||
/// </summary>
|
||||
PageManager CurrentSourcePageManager;
|
||||
private PageManager _currentSourcePageManager;
|
||||
|
||||
/// <summary>
|
||||
/// Will auto-timeout a power off
|
||||
/// </summary>
|
||||
CTimer PowerOffTimer;
|
||||
private CTimer _powerOffTimer;
|
||||
|
||||
ModalDialog PowerDownModal;
|
||||
private ModalDialog _powerDownModal;
|
||||
|
||||
public JoinedSigInterlock PopupInterlock { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The driver for the tech page. Lazy getter for memory usage
|
||||
/// </summary>
|
||||
PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver TechDriver
|
||||
EssentialsHuddleTechPageDriver TechDriver
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_TechDriver == null)
|
||||
_TechDriver = new PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver(TriList, CurrentRoom.PropertiesConfig.Tech);
|
||||
return _TechDriver;
|
||||
get {
|
||||
return _techDriver ??
|
||||
(_techDriver = new EssentialsHuddleTechPageDriver(TriList, CurrentRoom.PropertiesConfig.Tech));
|
||||
}
|
||||
}
|
||||
PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver _TechDriver;
|
||||
private EssentialsHuddleTechPageDriver _techDriver;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Controls timeout of notification ribbon timer
|
||||
/// </summary>
|
||||
CTimer RibbonTimer;
|
||||
private CTimer _ribbonTimer;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
@@ -182,25 +166,25 @@ namespace PepperDash.Essentials
|
||||
public EssentialsHuddlePanelAvFunctionsDriver(PanelDriverBase parent, CrestronTouchpanelPropertiesConfig config)
|
||||
: base(parent.TriList)
|
||||
{
|
||||
Config = config;
|
||||
Parent = parent;
|
||||
_config = config;
|
||||
_parent = parent;
|
||||
PopupInterlock = new JoinedSigInterlock(TriList);
|
||||
|
||||
SourcesSrl = new SubpageReferenceList(TriList, 3200, 3, 3, 3);
|
||||
ActivityFooterSrl = new SubpageReferenceList(TriList, 15022, 3, 3, 3);
|
||||
ShareButtonSig = ActivityFooterSrl.BoolInputSig(1, 1);
|
||||
_sourcesSrl = new SubpageReferenceList(TriList, 3200, 3, 3, 3);
|
||||
_activityFooterSrl = new SubpageReferenceList(TriList, 15022, 3, 3, 3);
|
||||
_shareButtonSig = _activityFooterSrl.BoolInputSig(1, 1);
|
||||
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
|
||||
ShowVolumeGauge = true;
|
||||
|
||||
// One-second pulse extender for volume gauge
|
||||
VolumeGaugeFeedback = new BoolFeedbackPulseExtender(1500);
|
||||
VolumeGaugeFeedback.Feedback
|
||||
_volumeGaugeFeedback = new BoolFeedbackPulseExtender(1500);
|
||||
_volumeGaugeFeedback.Feedback
|
||||
.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VolumeGaugePopupVisible]);
|
||||
|
||||
VolumeButtonsPopupFeedback = new BoolFeedbackPulseExtender(4000);
|
||||
VolumeButtonsPopupFeedback.Feedback
|
||||
_volumeButtonsPopupFeedback = new BoolFeedbackPulseExtender(4000);
|
||||
_volumeButtonsPopupFeedback.Feedback
|
||||
.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VolumeButtonPopupVisible]);
|
||||
|
||||
PowerOffTimeout = 30000;
|
||||
@@ -220,30 +204,19 @@ namespace PepperDash.Essentials
|
||||
return;
|
||||
}
|
||||
|
||||
var roomConf = CurrentRoom.PropertiesConfig;
|
||||
switch (_config.HeaderStyle.ToLower())
|
||||
{
|
||||
case CrestronTouchpanelPropertiesConfig.Habanero:
|
||||
TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () =>
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderPageVisible));
|
||||
break;
|
||||
case CrestronTouchpanelPropertiesConfig.Verbose:
|
||||
break;
|
||||
}
|
||||
|
||||
if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Habanero)
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () =>
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderPageVisible));
|
||||
}
|
||||
else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose)
|
||||
{
|
||||
// room name on join 1, concat phone and sip on join 2, no button method
|
||||
//var addr = roomConf.Addresses;
|
||||
//if (addr == null) // protect from missing values by using default empties
|
||||
// addr = new EssentialsRoomAddressPropertiesConfig();
|
||||
//// empty string when either missing, pipe when both showing
|
||||
//TriList.SetString(UIStringJoin.RoomAddressPipeText,
|
||||
// (string.IsNullOrEmpty(addr.PhoneNumber.Trim())
|
||||
// || string.IsNullOrEmpty(addr.SipAddress.Trim())) ? "" : " | ");
|
||||
//TriList.SetString(UIStringJoin.RoomPhoneText, addr.PhoneNumber);
|
||||
//TriList.SetString(UIStringJoin.RoomSipText, addr.SipAddress);
|
||||
}
|
||||
|
||||
TriList.SetBool(UIBoolJoin.DateAndTimeVisible, Config.ShowDate && Config.ShowTime);
|
||||
TriList.SetBool(UIBoolJoin.DateOnlyVisible, Config.ShowDate && !Config.ShowTime);
|
||||
TriList.SetBool(UIBoolJoin.TimeOnlyVisible, !Config.ShowDate && Config.ShowTime);
|
||||
TriList.SetBool(UIBoolJoin.DateAndTimeVisible, _config.ShowDate && _config.ShowTime);
|
||||
TriList.SetBool(UIBoolJoin.DateOnlyVisible, _config.ShowDate && !_config.ShowTime);
|
||||
TriList.SetBool(UIBoolJoin.TimeOnlyVisible, !_config.ShowDate && _config.ShowTime);
|
||||
|
||||
TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true);
|
||||
TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = true;
|
||||
@@ -330,7 +303,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.LogoUrlVisible, true);
|
||||
TriList.SetString(UIStringJoin.LogoUrl, _CurrentRoom.LogoUrl);
|
||||
TriList.SetString(UIStringJoin.LogoUrl, _currentRoom.LogoUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,7 +328,7 @@ namespace PepperDash.Essentials
|
||||
TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
//TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = false;
|
||||
VolumeButtonsPopupFeedback.ClearNow();
|
||||
_volumeButtonsPopupFeedback.ClearNow();
|
||||
//CancelPowerOff();
|
||||
|
||||
base.Hide();
|
||||
@@ -372,12 +345,12 @@ namespace PepperDash.Essentials
|
||||
TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, true);
|
||||
if (timeout > 0)
|
||||
{
|
||||
if (RibbonTimer != null)
|
||||
RibbonTimer.Stop();
|
||||
RibbonTimer = new CTimer(o =>
|
||||
if (_ribbonTimer != null)
|
||||
_ribbonTimer.Stop();
|
||||
_ribbonTimer = new CTimer(o =>
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, false);
|
||||
RibbonTimer = null;
|
||||
_ribbonTimer = null;
|
||||
}, timeout);
|
||||
}
|
||||
}
|
||||
@@ -388,10 +361,10 @@ namespace PepperDash.Essentials
|
||||
public void HideNotificationRibbon()
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, false);
|
||||
if (RibbonTimer != null)
|
||||
if (_ribbonTimer != null)
|
||||
{
|
||||
RibbonTimer.Stop();
|
||||
RibbonTimer = null;
|
||||
_ribbonTimer.Stop();
|
||||
_ribbonTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,7 +376,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
//Clear whatever is showing now.
|
||||
HideAndClearCurrentDisplayModeSigsInUse();
|
||||
CurrentDisplayMode = mode;
|
||||
_currentDisplayMode = mode;
|
||||
switch (mode)
|
||||
{
|
||||
case UiDisplayMode.PresentationMode:
|
||||
@@ -421,7 +394,7 @@ namespace PepperDash.Essentials
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
}
|
||||
// Date/time
|
||||
if (Config.ShowDate && Config.ShowTime)
|
||||
if (_config.ShowDate && _config.ShowTime)
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.DateAndTimeVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.DateOnlyVisible].BoolValue = false;
|
||||
@@ -430,8 +403,8 @@ namespace PepperDash.Essentials
|
||||
else
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.DateAndTimeVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.DateOnlyVisible].BoolValue = Config.ShowDate;
|
||||
TriList.BooleanInput[UIBoolJoin.TimeOnlyVisible].BoolValue = Config.ShowTime;
|
||||
TriList.BooleanInput[UIBoolJoin.DateOnlyVisible].BoolValue = _config.ShowDate;
|
||||
TriList.BooleanInput[UIBoolJoin.TimeOnlyVisible].BoolValue = _config.ShowTime;
|
||||
}
|
||||
|
||||
ShowCurrentDisplayModeSigsInUse();
|
||||
@@ -444,12 +417,12 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void SetupActivityFooterWhenRoomOff()
|
||||
{
|
||||
ActivityFooterSrl.Clear();
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl, 0,
|
||||
_activityFooterSrl.Clear();
|
||||
_activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, _activityFooterSrl, 0,
|
||||
b => { if (!b) ShareButtonPressed(); }));
|
||||
ActivityFooterSrl.Count = 1;
|
||||
_activityFooterSrl.Count = 1;
|
||||
TriList.UShortInput[UIUshortJoin.PresentationStagingCaretMode].UShortValue = 0;
|
||||
ShareButtonSig.BoolValue = false;
|
||||
_shareButtonSig.BoolValue = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -457,15 +430,15 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void SetupActivityFooterWhenRoomOn()
|
||||
{
|
||||
ActivityFooterSrl.Clear();
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl,
|
||||
_activityFooterSrl.Clear();
|
||||
_activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, _activityFooterSrl,
|
||||
0, null));
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl,
|
||||
_activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, _activityFooterSrl,
|
||||
4, b => { if (!b) PowerButtonPressed(); }));
|
||||
ActivityFooterSrl.Count = 2;
|
||||
_activityFooterSrl.Count = 2;
|
||||
TriList.UShortInput[UIUshortJoin.PresentationStagingCaretMode].UShortValue = 1;
|
||||
EndMeetingButtonSig = ActivityFooterSrl.BoolInputSig(2, 1);
|
||||
ShareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
|
||||
_endMeetingButtonSig = _activityFooterSrl.BoolInputSig(2, 1);
|
||||
_shareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -473,7 +446,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void ShareButtonPressed()
|
||||
{
|
||||
ShareButtonSig.BoolValue = true;
|
||||
_shareButtonSig.BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
|
||||
@@ -488,7 +461,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void ShowCurrentDisplayModeSigsInUse()
|
||||
{
|
||||
foreach (var sig in CurrentDisplayModeSigsInUse)
|
||||
foreach (var sig in _currentDisplayModeSigsInUse)
|
||||
sig.BoolValue = true;
|
||||
}
|
||||
|
||||
@@ -497,9 +470,9 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void HideAndClearCurrentDisplayModeSigsInUse()
|
||||
{
|
||||
foreach (var sig in CurrentDisplayModeSigsInUse)
|
||||
foreach (var sig in _currentDisplayModeSigsInUse)
|
||||
sig.BoolValue = false;
|
||||
CurrentDisplayModeSigsInUse.Clear();
|
||||
_currentDisplayModeSigsInUse.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -507,7 +480,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public override void BackButtonPressed()
|
||||
{
|
||||
switch (CurrentDisplayMode)
|
||||
switch (_currentDisplayMode)
|
||||
{
|
||||
case UiDisplayMode.PresentationMode:
|
||||
//CancelReturnToSourceTimer();
|
||||
@@ -522,7 +495,7 @@ namespace PepperDash.Essentials
|
||||
void BackToHome()
|
||||
{
|
||||
Hide();
|
||||
Parent.Show();
|
||||
_parent.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -534,26 +507,28 @@ namespace PepperDash.Essentials
|
||||
return;
|
||||
|
||||
var uiDev = CurrentRoom.CurrentSourceInfo.SourceDevice as IUiDisplayInfo;
|
||||
PageManager pm = null;
|
||||
// If we need a page manager, get an appropriate one
|
||||
if (uiDev != null)
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
// Got an existing page manager, get it
|
||||
if (PageManagers.ContainsKey(uiDev))
|
||||
pm = PageManagers[uiDev];
|
||||
// Otherwise make an apporiate one
|
||||
else if (uiDev is ISetTopBoxControls)
|
||||
//pm = new SetTopBoxMediumPageManager(uiDev as ISetTopBoxControls, TriList);
|
||||
pm = new SetTopBoxThreePanelPageManager(uiDev as ISetTopBoxControls, TriList);
|
||||
else if (uiDev is IDiscPlayerControls)
|
||||
pm = new DiscPlayerMediumPageManager(uiDev as IDiscPlayerControls, TriList);
|
||||
else
|
||||
pm = new DefaultPageManager(uiDev, TriList);
|
||||
PageManagers[uiDev] = pm;
|
||||
CurrentSourcePageManager = pm;
|
||||
pm.Show();
|
||||
}
|
||||
// If we need a page manager, get an appropriate one
|
||||
if (uiDev == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
// Got an existing page manager, get it
|
||||
PageManager pm;
|
||||
if (_pageManagers.ContainsKey(uiDev))
|
||||
pm = _pageManagers[uiDev];
|
||||
// Otherwise make an apporiate one
|
||||
else if (uiDev is ISetTopBoxControls)
|
||||
//pm = new SetTopBoxMediumPageManager(uiDev as ISetTopBoxControls, TriList);
|
||||
pm = new SetTopBoxThreePanelPageManager(uiDev as ISetTopBoxControls, TriList);
|
||||
else if (uiDev is IDiscPlayerControls)
|
||||
pm = new DiscPlayerMediumPageManager(uiDev as IDiscPlayerControls, TriList);
|
||||
else
|
||||
pm = new DefaultPageManager(uiDev, TriList);
|
||||
_pageManagers[uiDev] = pm;
|
||||
_currentSourcePageManager = pm;
|
||||
pm.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -564,7 +539,7 @@ namespace PepperDash.Essentials
|
||||
void UiSelectSource(string key)
|
||||
{
|
||||
// Run the route and when it calls back, show the source
|
||||
CurrentRoom.RunRouteAction(key, new Action(() => { }));
|
||||
CurrentRoom.RunRouteAction(key, () => { });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -588,12 +563,12 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
// Do we need to check where the UI is? No?
|
||||
var timer = CurrentRoom.ShutdownPromptTimer;
|
||||
EndMeetingButtonSig.BoolValue = true;
|
||||
ShareButtonSig.BoolValue = false;
|
||||
_endMeetingButtonSig.BoolValue = true;
|
||||
_shareButtonSig.BoolValue = false;
|
||||
|
||||
if (CurrentRoom.ShutdownType == eShutdownType.Manual || CurrentRoom.ShutdownType == eShutdownType.Vacancy)
|
||||
{
|
||||
PowerDownModal = new ModalDialog(TriList);
|
||||
_powerDownModal = new ModalDialog(TriList);
|
||||
var message = string.Format("Meeting will end in {0} seconds", CurrentRoom.ShutdownPromptSeconds);
|
||||
|
||||
// Attach timer things to modal
|
||||
@@ -607,15 +582,15 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
if (!onFb.BoolValue)
|
||||
{
|
||||
EndMeetingButtonSig.BoolValue = false;
|
||||
PowerDownModal.HideDialog();
|
||||
_endMeetingButtonSig.BoolValue = false;
|
||||
_powerDownModal.HideDialog();
|
||||
onFb.OutputChange -= offHandler;
|
||||
//gauge.OutputChange -= gaugeHandler;
|
||||
}
|
||||
};
|
||||
onFb.OutputChange += offHandler;
|
||||
|
||||
PowerDownModal.PresentModalDialog(2, "End Meeting", "Power", message, "Cancel", "End Meeting Now", true, true,
|
||||
_powerDownModal.PresentModalDialog(2, "End Meeting", "Power", message, "Cancel", "End Meeting Now", true, true,
|
||||
but =>
|
||||
{
|
||||
if (but != 2) // any button except for End cancels
|
||||
@@ -633,7 +608,7 @@ namespace PepperDash.Essentials
|
||||
/// <param name="e"></param>
|
||||
void ShutdownPromptTimer_HasFinished(object sender, EventArgs e)
|
||||
{
|
||||
EndMeetingButtonSig.BoolValue = false;
|
||||
_endMeetingButtonSig.BoolValue = false;
|
||||
CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange -= ShutdownPromptTimer_TimeRemainingFeedback_OutputChange;
|
||||
CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= ShutdownPromptTimer_PercentFeedback_OutputChange;
|
||||
}
|
||||
@@ -645,10 +620,10 @@ namespace PepperDash.Essentials
|
||||
/// <param name="e"></param>
|
||||
void ShutdownPromptTimer_WasCancelled(object sender, EventArgs e)
|
||||
{
|
||||
if (PowerDownModal != null)
|
||||
PowerDownModal.HideDialog();
|
||||
EndMeetingButtonSig.BoolValue = false;
|
||||
ShareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
|
||||
if (_powerDownModal != null)
|
||||
_powerDownModal.HideDialog();
|
||||
_endMeetingButtonSig.BoolValue = false;
|
||||
_shareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
|
||||
|
||||
CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange += ShutdownPromptTimer_TimeRemainingFeedback_OutputChange;
|
||||
CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= ShutdownPromptTimer_PercentFeedback_OutputChange;
|
||||
@@ -656,27 +631,38 @@ namespace PepperDash.Essentials
|
||||
|
||||
void ShutdownPromptTimer_TimeRemainingFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
var stringFeedback = sender as StringFeedback;
|
||||
if (stringFeedback == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var message = string.Format("Meeting will end in {0} seconds", (sender as StringFeedback).StringValue);
|
||||
var message = string.Format("Meeting will end in {0} seconds", stringFeedback.StringValue);
|
||||
TriList.StringInput[ModalDialog.MessageTextJoin].StringValue = message;
|
||||
}
|
||||
|
||||
void ShutdownPromptTimer_PercentFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
var value = (ushort)((sender as IntFeedback).UShortValue * 65535 / 100);
|
||||
TriList.UShortInput[ModalDialog.TimerGaugeJoin].UShortValue = value;
|
||||
}
|
||||
void ShutdownPromptTimer_PercentFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
var intFeedback = sender as IntFeedback;
|
||||
if (intFeedback == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var value = (ushort)(intFeedback.UShortValue * 65535 / 100);
|
||||
TriList.UShortInput[ModalDialog.TimerGaugeJoin].UShortValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void CancelPowerOffTimer()
|
||||
{
|
||||
if (PowerOffTimer != null)
|
||||
{
|
||||
PowerOffTimer.Stop();
|
||||
PowerOffTimer = null;
|
||||
}
|
||||
if (_powerOffTimer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_powerOffTimer.Stop();
|
||||
_powerOffTimer = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -684,13 +670,13 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void VolumeButtonsTogglePress()
|
||||
{
|
||||
if (VolumeButtonsPopupFeedback.BoolValue)
|
||||
VolumeButtonsPopupFeedback.ClearNow();
|
||||
if (_volumeButtonsPopupFeedback.BoolValue)
|
||||
_volumeButtonsPopupFeedback.ClearNow();
|
||||
else
|
||||
{
|
||||
// Trigger the popup
|
||||
VolumeButtonsPopupFeedback.BoolValue = true;
|
||||
VolumeButtonsPopupFeedback.BoolValue = false;
|
||||
_volumeButtonsPopupFeedback.BoolValue = true;
|
||||
_volumeButtonsPopupFeedback.BoolValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -702,8 +688,8 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
// extend timeouts
|
||||
if (ShowVolumeGauge)
|
||||
VolumeGaugeFeedback.BoolValue = state;
|
||||
VolumeButtonsPopupFeedback.BoolValue = state;
|
||||
_volumeGaugeFeedback.BoolValue = state;
|
||||
_volumeButtonsPopupFeedback.BoolValue = state;
|
||||
if (CurrentRoom.CurrentVolumeControls != null)
|
||||
CurrentRoom.CurrentVolumeControls.VolumeUp(state);
|
||||
}
|
||||
@@ -716,8 +702,8 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
// extend timeouts
|
||||
if (ShowVolumeGauge)
|
||||
VolumeGaugeFeedback.BoolValue = state;
|
||||
VolumeButtonsPopupFeedback.BoolValue = state;
|
||||
_volumeGaugeFeedback.BoolValue = state;
|
||||
_volumeButtonsPopupFeedback.BoolValue = state;
|
||||
if (CurrentRoom.CurrentVolumeControls != null)
|
||||
CurrentRoom.CurrentVolumeControls.VolumeDown(state);
|
||||
}
|
||||
@@ -728,31 +714,31 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public void RefreshCurrentRoom(EssentialsHuddleSpaceRoom room)
|
||||
{
|
||||
if (_CurrentRoom != null)
|
||||
if (_currentRoom != null)
|
||||
{
|
||||
// Disconnect current room
|
||||
_CurrentRoom.CurrentVolumeDeviceChange -= this.CurrentRoom_CurrentAudioDeviceChange;
|
||||
_currentRoom.CurrentVolumeDeviceChange -= CurrentRoom_CurrentAudioDeviceChange;
|
||||
ClearAudioDeviceConnections();
|
||||
_CurrentRoom.CurrentSourceChange -= this.CurrentRoom_SourceInfoChange;
|
||||
DisconnectSource(_CurrentRoom.CurrentSourceInfo);
|
||||
_CurrentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted;
|
||||
_CurrentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished;
|
||||
_CurrentRoom.ShutdownPromptTimer.WasCancelled -= ShutdownPromptTimer_WasCancelled;
|
||||
_currentRoom.CurrentSourceChange -= CurrentRoom_SourceInfoChange;
|
||||
DisconnectSource(_currentRoom.CurrentSourceInfo);
|
||||
_currentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted;
|
||||
_currentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished;
|
||||
_currentRoom.ShutdownPromptTimer.WasCancelled -= ShutdownPromptTimer_WasCancelled;
|
||||
|
||||
_CurrentRoom.OnFeedback.OutputChange -= CurrentRoom_OnFeedback_OutputChange;
|
||||
_CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
|
||||
_CurrentRoom.IsCoolingDownFeedback.OutputChange -= IsCoolingDownFeedback_OutputChange;
|
||||
_currentRoom.OnFeedback.OutputChange -= CurrentRoom_OnFeedback_OutputChange;
|
||||
_currentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
|
||||
_currentRoom.IsCoolingDownFeedback.OutputChange -= IsCoolingDownFeedback_OutputChange;
|
||||
}
|
||||
|
||||
_CurrentRoom = room;
|
||||
_currentRoom = room;
|
||||
|
||||
if (_CurrentRoom != null)
|
||||
if (_currentRoom != null)
|
||||
{
|
||||
// get the source list config and set up the source list
|
||||
var config = ConfigReader.ConfigObject.SourceLists;
|
||||
if (config.ContainsKey(_CurrentRoom.SourceListKey))
|
||||
if (config.ContainsKey(_currentRoom.SourceListKey))
|
||||
{
|
||||
var srcList = config[_CurrentRoom.SourceListKey];
|
||||
var srcList = config[_currentRoom.SourceListKey];
|
||||
// Setup sources list
|
||||
uint i = 1; // counter for UI list
|
||||
foreach (var kvp in srcList)
|
||||
@@ -769,16 +755,16 @@ namespace PepperDash.Essentials
|
||||
continue;
|
||||
}
|
||||
var routeKey = kvp.Key;
|
||||
var item = new SubpageReferenceListSourceItem(i++, SourcesSrl, srcConfig,
|
||||
var item = new SubpageReferenceListSourceItem(i++, _sourcesSrl, srcConfig,
|
||||
b => { if (!b) UiSelectSource(routeKey); });
|
||||
SourcesSrl.AddItem(item); // add to the SRL
|
||||
item.RegisterForSourceChange(_CurrentRoom);
|
||||
_sourcesSrl.AddItem(item); // add to the SRL
|
||||
item.RegisterForSourceChange(_currentRoom);
|
||||
}
|
||||
SourcesSrl.Count = (ushort)(i - 1);
|
||||
_sourcesSrl.Count = (ushort)(i - 1);
|
||||
}
|
||||
// Name and logo
|
||||
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _CurrentRoom.Name;
|
||||
if (_CurrentRoom.LogoUrl == null)
|
||||
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _currentRoom.Name;
|
||||
if (_currentRoom.LogoUrl == null)
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = false;
|
||||
@@ -787,26 +773,31 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = true;
|
||||
TriList.StringInput[UIStringJoin.LogoUrl].StringValue = _CurrentRoom.LogoUrl;
|
||||
TriList.StringInput[UIStringJoin.LogoUrl].StringValue = _currentRoom.LogoUrl;
|
||||
}
|
||||
|
||||
// Shutdown timer
|
||||
_CurrentRoom.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted;
|
||||
_CurrentRoom.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished;
|
||||
_CurrentRoom.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled;
|
||||
_currentRoom.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted;
|
||||
_currentRoom.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished;
|
||||
_currentRoom.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled;
|
||||
|
||||
// Link up all the change events from the room
|
||||
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
|
||||
_currentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
|
||||
CurrentRoom_SyncOnFeedback();
|
||||
_CurrentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange;
|
||||
_CurrentRoom.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
|
||||
_currentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange;
|
||||
_currentRoom.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
|
||||
|
||||
_CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
|
||||
_currentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
|
||||
RefreshAudioDeviceConnections();
|
||||
_CurrentRoom.CurrentSourceChange += CurrentRoom_SourceInfoChange;
|
||||
_currentRoom.CurrentSourceChange += CurrentRoom_SourceInfoChange;
|
||||
RefreshSourceInfo();
|
||||
|
||||
(Parent as EssentialsPanelMainInterfaceDriver).HeaderDriver.SetupHeaderButtons(this, CurrentRoom);
|
||||
var essentialsPanelMainInterfaceDriver = _parent as EssentialsPanelMainInterfaceDriver;
|
||||
|
||||
if (essentialsPanelMainInterfaceDriver != null)
|
||||
{
|
||||
essentialsPanelMainInterfaceDriver.HeaderDriver.SetupHeaderButtons(this, CurrentRoom);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -817,7 +808,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
void SetCurrentRoom(EssentialsHuddleSpaceRoom room)
|
||||
{
|
||||
if (_CurrentRoom == room) return;
|
||||
if (_currentRoom == room) return;
|
||||
// Disconnect current (probably never called)
|
||||
|
||||
room.ConfigChanged -= room_ConfigChanged;
|
||||
@@ -833,7 +824,7 @@ namespace PepperDash.Essentials
|
||||
/// <param name="e"></param>
|
||||
void room_ConfigChanged(object sender, EventArgs e)
|
||||
{
|
||||
RefreshCurrentRoom(_CurrentRoom);
|
||||
RefreshCurrentRoom(_currentRoom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -846,7 +837,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
void CurrentRoom_SyncOnFeedback()
|
||||
{
|
||||
var value = _CurrentRoom.OnFeedback.BoolValue;
|
||||
var value = _currentRoom.OnFeedback.BoolValue;
|
||||
//Debug.Console(2, CurrentRoom, "UI: Is on event={0}", value);
|
||||
TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value;
|
||||
|
||||
@@ -908,15 +899,14 @@ namespace PepperDash.Essentials
|
||||
// Hide whatever is showing
|
||||
if (IsVisible)
|
||||
{
|
||||
if (CurrentSourcePageManager != null)
|
||||
if (_currentSourcePageManager != null)
|
||||
{
|
||||
CurrentSourcePageManager.Hide();
|
||||
CurrentSourcePageManager = null;
|
||||
_currentSourcePageManager.Hide();
|
||||
_currentSourcePageManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (previousInfo == null) return;
|
||||
var previousDev = previousInfo.SourceDevice;
|
||||
var previousDev = previousInfo.SourceDevice;
|
||||
|
||||
// device type interfaces
|
||||
if (previousDev is ISetTopBoxControls)
|
||||
@@ -947,7 +937,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
var routeInfo = CurrentRoom.CurrentSourceInfo;
|
||||
// This will show off popup too
|
||||
if (this.IsVisible)
|
||||
if (IsVisible)
|
||||
ShowCurrentSource();
|
||||
|
||||
if (routeInfo == null)// || !CurrentRoom.OnFeedback.BoolValue)
|
||||
@@ -955,22 +945,23 @@ namespace PepperDash.Essentials
|
||||
// Check for power off and insert "Room is off"
|
||||
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "Room is off";
|
||||
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Power";
|
||||
this.Hide();
|
||||
Parent.Show();
|
||||
Hide();
|
||||
_parent.Show();
|
||||
return;
|
||||
}
|
||||
else if (CurrentRoom.CurrentSourceInfo != null)
|
||||
{
|
||||
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = routeInfo.PreferredName;
|
||||
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = routeInfo.Icon; // defaults to "blank"
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "---";
|
||||
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Blank";
|
||||
}
|
||||
|
||||
// Connect controls
|
||||
|
||||
if (CurrentRoom.CurrentSourceInfo != null)
|
||||
{
|
||||
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = routeInfo.PreferredName;
|
||||
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = routeInfo.Icon; // defaults to "blank"
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "---";
|
||||
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Blank";
|
||||
}
|
||||
|
||||
// Connect controls
|
||||
if (routeInfo.SourceDevice != null)
|
||||
ConnectControlDeviceMethods(routeInfo.SourceDevice);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
|
||||
using PepperDash.Essentials.Devices.Displays;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
|
||||
namespace PepperDash.Essentials.UIDrivers
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
16
PepperDashEssentials/UIDrivers/IHasCalendarButton.cs
Normal file
16
PepperDashEssentials/UIDrivers/IHasCalendarButton.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public interface IHasCalendarButton
|
||||
{
|
||||
EssentialsHuddleVtc1Room CurrentRoom { get; }
|
||||
void CalendarPress();
|
||||
}
|
||||
|
||||
public interface IHasCallButton
|
||||
{
|
||||
EssentialsHuddleVtc1Room CurrentRoom { get; }
|
||||
void ShowActiveCallsList();
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,12 @@ using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Devices.VideoCodec;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Core.VideoCodec;
|
||||
|
||||
namespace PepperDash.Essentials.UIDrivers.VC
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash_Essentials_Core.Devices;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
@@ -23,7 +24,10 @@ namespace PepperDash.Essentials.Core.Config
|
||||
[JsonProperty("sourceLists")]
|
||||
public Dictionary<string, Dictionary<string, SourceListItem>> SourceLists { get; set; }
|
||||
|
||||
[JsonProperty("tieLines")]
|
||||
[JsonProperty("destinationLists")]
|
||||
public Dictionary<string, Dictionary<string, DestinationListItem>> DestinationLists { get; set; }
|
||||
|
||||
[JsonProperty("tieLines")]
|
||||
public List<TieLineConfig> TieLines { get; set; }
|
||||
|
||||
[JsonProperty("joinMaps")]
|
||||
@@ -40,8 +44,16 @@ namespace PepperDash.Essentials.Core.Config
|
||||
return SourceLists[key];
|
||||
}
|
||||
|
||||
public Dictionary<string, DestinationListItem> GetDestinationListForKey(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key) || !DestinationLists.ContainsKey(key))
|
||||
return null;
|
||||
|
||||
return DestinationLists[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks Devices for an item with a Key that matches and returns it if found. Otherwise, retunes null
|
||||
/// Checks Devices for an item with a Key that matches and returns it if found. Otherwise, returns null
|
||||
/// </summary>
|
||||
/// <param name="key">Key of desired device</param>
|
||||
/// <returns></returns>
|
||||
@@ -52,12 +64,9 @@ namespace PepperDash.Essentials.Core.Config
|
||||
|
||||
var deviceConfig = Devices.FirstOrDefault(d => d.Key.Equals(key));
|
||||
|
||||
if (deviceConfig != null)
|
||||
return deviceConfig;
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
//removed if statement that was here...
|
||||
//DeviceConfig will be null if it's not found in the list
|
||||
return deviceConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
|
||||
{
|
||||
public class CodecActiveCallItem
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("number")]
|
||||
public string Number { get; set; }
|
||||
|
||||
[JsonProperty("type")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eCodecCallType Type { get; set; }
|
||||
|
||||
[JsonProperty("status")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eCodecCallStatus Status { get; set; }
|
||||
|
||||
[JsonProperty("direction")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eCodecCallDirection Direction { get; set; }
|
||||
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
//public object CallMetaData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true when this call is any status other than
|
||||
/// Unknown, Disconnected, Disconnecting
|
||||
/// </summary>
|
||||
[JsonProperty("isActiveCall")]
|
||||
public bool IsActiveCall
|
||||
{
|
||||
get
|
||||
{
|
||||
return !(Status == eCodecCallStatus.Disconnected
|
||||
|| Status == eCodecCallStatus.Disconnecting
|
||||
|| Status == eCodecCallStatus.Idle
|
||||
|| Status == eCodecCallStatus.Unknown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CodecCallStatusItemChangeEventArgs : EventArgs
|
||||
{
|
||||
public CodecActiveCallItem CallItem { get; private set; }
|
||||
|
||||
public CodecCallStatusItemChangeEventArgs(CodecActiveCallItem item)
|
||||
{
|
||||
CallItem = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
|
||||
{
|
||||
public enum eCodecCallDirection
|
||||
{
|
||||
Unknown = 0, Incoming, Outgoing
|
||||
}
|
||||
|
||||
public class CodecCallDirection
|
||||
{
|
||||
/// <summary>
|
||||
/// Takes the Cisco call type and converts to the matching enum
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
public static eCodecCallDirection ConvertToDirectionEnum(string s)
|
||||
{
|
||||
switch (s.ToLower())
|
||||
{
|
||||
case "incoming":
|
||||
{
|
||||
return eCodecCallDirection.Incoming;
|
||||
}
|
||||
case "outgoing":
|
||||
{
|
||||
return eCodecCallDirection.Outgoing;
|
||||
}
|
||||
default:
|
||||
return eCodecCallDirection.Unknown;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
public enum eCodecCallStatus
|
||||
{
|
||||
Unknown = 0,
|
||||
Connected,
|
||||
Connecting,
|
||||
Dialing,
|
||||
Disconnected,
|
||||
Disconnecting,
|
||||
EarlyMedia,
|
||||
Idle,
|
||||
OnHold,
|
||||
Ringing,
|
||||
Preserved,
|
||||
RemotePreserved,
|
||||
}
|
||||
|
||||
|
||||
public class CodecCallStatus
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Takes the Cisco call type and converts to the matching enum
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
public static eCodecCallStatus ConvertToStatusEnum(string s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case "Connected":
|
||||
{
|
||||
return eCodecCallStatus.Connected;
|
||||
}
|
||||
case "Connecting":
|
||||
{
|
||||
return eCodecCallStatus.Connecting;
|
||||
}
|
||||
case "Dialling":
|
||||
{
|
||||
return eCodecCallStatus.Dialing;
|
||||
}
|
||||
case "Disconnected":
|
||||
{
|
||||
return eCodecCallStatus.Disconnected;
|
||||
}
|
||||
case "Disconnecting":
|
||||
{
|
||||
return eCodecCallStatus.Disconnecting;
|
||||
}
|
||||
case "EarlyMedia":
|
||||
{
|
||||
return eCodecCallStatus.EarlyMedia;
|
||||
}
|
||||
case "Idle":
|
||||
{
|
||||
return eCodecCallStatus.Idle;
|
||||
}
|
||||
case "OnHold":
|
||||
{
|
||||
return eCodecCallStatus.OnHold;
|
||||
}
|
||||
case "Ringing":
|
||||
{
|
||||
return eCodecCallStatus.Ringing;
|
||||
}
|
||||
case "Preserved":
|
||||
{
|
||||
return eCodecCallStatus.Preserved;
|
||||
}
|
||||
case "RemotePreserved":
|
||||
{
|
||||
return eCodecCallStatus.RemotePreserved;
|
||||
}
|
||||
default:
|
||||
return eCodecCallStatus.Unknown;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
|
||||
{
|
||||
public enum eCodecCallType
|
||||
{
|
||||
Unknown = 0,
|
||||
Audio,
|
||||
Video,
|
||||
AudioCanEscalate,
|
||||
ForwardAllCall
|
||||
}
|
||||
|
||||
public class CodecCallType
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Takes the Cisco call type and converts to the matching enum
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
public static eCodecCallType ConvertToTypeEnum(string s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case "Audio":
|
||||
{
|
||||
return eCodecCallType.Audio;
|
||||
}
|
||||
case "Video":
|
||||
{
|
||||
return eCodecCallType.Video;
|
||||
}
|
||||
case "AudioCanEscalate":
|
||||
{
|
||||
return eCodecCallType.AudioCanEscalate;
|
||||
}
|
||||
case "ForwardAllCall":
|
||||
{
|
||||
return eCodecCallType.ForwardAllCall;
|
||||
}
|
||||
default:
|
||||
return eCodecCallType.Unknown;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
public enum eMeetingPrivacy
|
||||
{
|
||||
Unknown = 0,
|
||||
Public,
|
||||
Private
|
||||
}
|
||||
|
||||
public class CodecCallPrivacy
|
||||
{
|
||||
/// <summary>
|
||||
/// Takes the Cisco privacy type and converts to the matching enum
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
public static eMeetingPrivacy ConvertToDirectionEnum(string s)
|
||||
{
|
||||
switch (s.ToLower())
|
||||
{
|
||||
case "public":
|
||||
{
|
||||
return eMeetingPrivacy.Public;
|
||||
}
|
||||
case "private":
|
||||
{
|
||||
return eMeetingPrivacy.Private;
|
||||
}
|
||||
default:
|
||||
return eMeetingPrivacy.Unknown;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines minimum volume controls for a codec device with dialing capabilities
|
||||
/// </summary>
|
||||
public interface ICodecAudio : IBasicVolumeWithFeedback, IPrivacy
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
public interface IHasCallFavorites
|
||||
{
|
||||
CodecCallFavorites CallFavorites { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents favorites entries for a codec device
|
||||
/// </summary>
|
||||
public class CodecCallFavorites
|
||||
{
|
||||
public List<CodecActiveCallItem> Favorites { get; set; }
|
||||
|
||||
public CodecCallFavorites()
|
||||
{
|
||||
Favorites = new List<CodecActiveCallItem>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
public interface IHasCallHistory
|
||||
{
|
||||
CodecCallHistory CallHistory { get; }
|
||||
|
||||
void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry);
|
||||
}
|
||||
|
||||
public enum eCodecOccurrenceType
|
||||
{
|
||||
Unknown = 0,
|
||||
Placed,
|
||||
Received,
|
||||
NoAnswer
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the recent call history for a codec device
|
||||
/// </summary>
|
||||
public class CodecCallHistory
|
||||
{
|
||||
public event EventHandler<EventArgs> RecentCallsListHasChanged;
|
||||
|
||||
public List<CallHistoryEntry> RecentCalls { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Item that gets added to the list when there are no recent calls in history
|
||||
/// </summary>
|
||||
readonly CallHistoryEntry _listEmptyEntry;
|
||||
|
||||
public CallHistoryEntry ListEmptyEntry
|
||||
{
|
||||
get { return _listEmptyEntry; }
|
||||
}
|
||||
|
||||
public CodecCallHistory()
|
||||
{
|
||||
_listEmptyEntry = new CallHistoryEntry() { Name = "No Recent Calls" };
|
||||
|
||||
RecentCalls = new List<CallHistoryEntry> {_listEmptyEntry};
|
||||
}
|
||||
|
||||
private void OnRecentCallsListChange()
|
||||
{
|
||||
var handler = RecentCallsListHasChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveEntry(CallHistoryEntry entry)
|
||||
{
|
||||
RecentCalls.Remove(entry);
|
||||
OnRecentCallsListChange();
|
||||
}
|
||||
|
||||
public void UpdateCallHistory(List<CallHistoryEntry> newList)
|
||||
{
|
||||
RecentCalls = newList;
|
||||
|
||||
OnRecentCallsListChange();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generic call history entry, not device specific
|
||||
/// </summary>
|
||||
public class CallHistoryEntry : CodecActiveCallItem
|
||||
{
|
||||
[JsonConverter(typeof (IsoDateTimeConverter))]
|
||||
[JsonProperty("startTime")]
|
||||
public DateTime StartTime { get; set; }
|
||||
|
||||
[JsonConverter(typeof (StringEnumConverter))]
|
||||
[JsonProperty("occurrenceType")]
|
||||
public eCodecOccurrenceType OccurrenceType { get; set; }
|
||||
|
||||
[JsonProperty("occurrenceHistoryId")]
|
||||
public string OccurrenceHistoryId { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
public interface IHasContentSharing
|
||||
{
|
||||
BoolFeedback SharingContentIsOnFeedback { get; }
|
||||
StringFeedback SharingSourceFeedback { get; }
|
||||
|
||||
bool AutoShareContentWhileInCall { get; }
|
||||
|
||||
void StartSharing();
|
||||
void StopSharing();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Requirements for a device that has dialing capabilities
|
||||
/// </summary>
|
||||
public interface IHasDialer
|
||||
{
|
||||
// Add requirements for Dialer functionality
|
||||
|
||||
event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
|
||||
|
||||
void Dial(string number);
|
||||
void EndCall(CodecActiveCallItem activeCall);
|
||||
void EndAllCalls();
|
||||
void AcceptCall(CodecActiveCallItem item);
|
||||
void RejectCall(CodecActiveCallItem item);
|
||||
void SendDtmf(string digit);
|
||||
|
||||
bool IsInCall { get; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using PepperDash.Essentials.Core.Devices.VideoCodec;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the API for codecs with a directory
|
||||
/// </summary>
|
||||
public interface IHasDirectory
|
||||
{
|
||||
event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
|
||||
|
||||
CodecDirectory DirectoryRoot { get; }
|
||||
|
||||
CodecDirectory CurrentDirectoryResult { get; }
|
||||
|
||||
CodecPhonebookSyncState PhonebookSyncState { get; }
|
||||
|
||||
void SearchDirectory(string searchString);
|
||||
|
||||
void GetDirectoryFolderContents(string folderId);
|
||||
|
||||
void SetCurrentDirectoryToRoot();
|
||||
|
||||
void GetDirectoryParentFolderContents();
|
||||
|
||||
BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the directory browse history when browsing beyond the root directory
|
||||
/// </summary>
|
||||
List<CodecDirectory> DirectoryBrowseHistory { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class DirectoryEventArgs : EventArgs
|
||||
{
|
||||
public CodecDirectory Directory { get; set; }
|
||||
public bool DirectoryIsOnRoot { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a codec directory
|
||||
/// </summary>
|
||||
public class CodecDirectory
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the contents of the directory
|
||||
/// </summary>
|
||||
[JsonProperty("directoryResults")]
|
||||
public List<DirectoryItem> CurrentDirectoryResults { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to store the ID of the current folder for CurrentDirectoryResults
|
||||
/// </summary>
|
||||
[JsonProperty("resultsFolderId")]
|
||||
public string ResultsFolderId { get; set; }
|
||||
|
||||
public CodecDirectory()
|
||||
{
|
||||
CurrentDirectoryResults = new List<DirectoryItem>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds folders to the directory
|
||||
/// </summary>
|
||||
/// <param name="folders"></param>
|
||||
public void AddFoldersToDirectory(List<DirectoryItem> folders)
|
||||
{
|
||||
if(folders != null)
|
||||
CurrentDirectoryResults.AddRange(folders);
|
||||
|
||||
SortDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds contacts to the directory
|
||||
/// </summary>
|
||||
/// <param name="contacts"></param>
|
||||
public void AddContactsToDirectory(List<DirectoryItem> contacts)
|
||||
{
|
||||
if(contacts != null)
|
||||
CurrentDirectoryResults.AddRange(contacts);
|
||||
|
||||
SortDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the DirectoryResults list to display all folders alphabetically, then all contacts alphabetically
|
||||
/// </summary>
|
||||
private void SortDirectory()
|
||||
{
|
||||
var sortedFolders = new List<DirectoryItem>();
|
||||
|
||||
sortedFolders.AddRange(CurrentDirectoryResults.Where(f => f is DirectoryFolder));
|
||||
|
||||
sortedFolders.OrderBy(f => f.Name);
|
||||
|
||||
var sortedContacts = new List<DirectoryItem>();
|
||||
|
||||
sortedContacts.AddRange(CurrentDirectoryResults.Where(c => c is DirectoryContact));
|
||||
|
||||
sortedFolders.OrderBy(c => c.Name);
|
||||
|
||||
CurrentDirectoryResults.Clear();
|
||||
|
||||
CurrentDirectoryResults.AddRange(sortedFolders);
|
||||
|
||||
CurrentDirectoryResults.AddRange(sortedContacts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to decorate a contact to indicate it can be invided to a meeting
|
||||
/// </summary>
|
||||
public interface IInvitableContact
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an item in the directory
|
||||
/// </summary>
|
||||
public class DirectoryItem : ICloneable
|
||||
{
|
||||
public object Clone()
|
||||
{
|
||||
return this.MemberwiseClone();
|
||||
}
|
||||
|
||||
[JsonProperty("folderId")]
|
||||
public string FolderId { get; set; }
|
||||
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a folder type DirectoryItem
|
||||
/// </summary>
|
||||
public class DirectoryFolder : DirectoryItem
|
||||
{
|
||||
[JsonProperty("contacts")]
|
||||
public List<DirectoryContact> Contacts { get; set; }
|
||||
|
||||
[JsonProperty("parentFolderId")]
|
||||
public string ParentFolderId { get; set; }
|
||||
|
||||
public DirectoryFolder()
|
||||
{
|
||||
Contacts = new List<DirectoryContact>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a contact type DirectoryItem
|
||||
/// </summary>
|
||||
public class DirectoryContact : DirectoryItem
|
||||
{
|
||||
[JsonProperty("contactId")]
|
||||
public string ContactId { get; set; }
|
||||
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
[JsonProperty("contactMethods")]
|
||||
public List<ContactMethod> ContactMethods { get; set; }
|
||||
|
||||
public DirectoryContact()
|
||||
{
|
||||
ContactMethods = new List<ContactMethod>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a method of contact for a contact
|
||||
/// </summary>
|
||||
public class ContactMethod
|
||||
{
|
||||
[JsonProperty("contactMethodId")]
|
||||
public string ContactMethodId { get; set; }
|
||||
|
||||
[JsonProperty("number")]
|
||||
public string Number { get; set; }
|
||||
|
||||
[JsonProperty("device")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eContactMethodDevice Device { get; set; }
|
||||
|
||||
[JsonProperty("callType")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eContactMethodCallType CallType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum eContactMethodDevice
|
||||
{
|
||||
Unknown = 0,
|
||||
Mobile,
|
||||
Other,
|
||||
Telephone,
|
||||
Video
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum eContactMethodCallType
|
||||
{
|
||||
Unknown = 0,
|
||||
Audio,
|
||||
Video
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
public enum eMeetingEventChangeType
|
||||
{
|
||||
Unkown = 0,
|
||||
MeetingStartWarning,
|
||||
MeetingStart,
|
||||
MeetingEndWarning,
|
||||
MeetingEnd
|
||||
}
|
||||
|
||||
public interface IHasScheduleAwareness
|
||||
{
|
||||
CodecScheduleAwareness CodecSchedule { get; }
|
||||
|
||||
void GetSchedule();
|
||||
}
|
||||
|
||||
public class CodecScheduleAwareness
|
||||
{
|
||||
List<Meeting> _Meetings;
|
||||
|
||||
public event EventHandler<MeetingEventArgs> MeetingEventChange;
|
||||
|
||||
public event EventHandler<EventArgs> MeetingsListHasChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Setter triggers MeetingsListHasChanged event
|
||||
/// </summary>
|
||||
public List<Meeting> Meetings
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Meetings;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Meetings = value;
|
||||
|
||||
var handler = MeetingsListHasChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CTimer ScheduleChecker;
|
||||
|
||||
public CodecScheduleAwareness()
|
||||
{
|
||||
Meetings = new List<Meeting>();
|
||||
|
||||
ScheduleChecker = new CTimer(CheckSchedule, null, 1000, 1000);
|
||||
}
|
||||
|
||||
private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting)
|
||||
{
|
||||
var handler = MeetingEventChange;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckSchedule(object o)
|
||||
{
|
||||
// Iterate the meeting list and check if any meeting need to do anythingk
|
||||
|
||||
const double meetingTimeEpsilon = 0.0001;
|
||||
foreach (Meeting m in Meetings)
|
||||
{
|
||||
eMeetingEventChangeType changeType = eMeetingEventChangeType.Unkown;
|
||||
|
||||
if (m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to start
|
||||
changeType = eMeetingEventChangeType.MeetingStartWarning;
|
||||
else if (Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
|
||||
changeType = eMeetingEventChangeType.MeetingStart;
|
||||
else if (m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to end
|
||||
changeType = eMeetingEventChangeType.MeetingEndWarning;
|
||||
else if (Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
|
||||
changeType = eMeetingEventChangeType.MeetingEnd;
|
||||
|
||||
if (changeType != eMeetingEventChangeType.Unkown)
|
||||
OnMeetingChange(changeType, m);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generic class to represent a meeting (Cisco or Polycom OBTP or Fusion)
|
||||
/// </summary>
|
||||
public class Meeting
|
||||
{
|
||||
public TimeSpan MeetingWarningMinutes = TimeSpan.FromMinutes(5);
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Organizer { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Agenda { get; set; }
|
||||
public TimeSpan TimeToMeetingStart
|
||||
{
|
||||
get
|
||||
{
|
||||
return StartTime - DateTime.Now;
|
||||
}
|
||||
}
|
||||
public TimeSpan TimeToMeetingEnd
|
||||
{
|
||||
get
|
||||
{
|
||||
return EndTime - DateTime.Now;
|
||||
}
|
||||
}
|
||||
public DateTime StartTime { get; set; }
|
||||
public DateTime EndTime { get; set; }
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return EndTime - StartTime;
|
||||
}
|
||||
}
|
||||
public eMeetingPrivacy Privacy { get; set; }
|
||||
public bool Joinable
|
||||
{
|
||||
get
|
||||
{
|
||||
return StartTime.AddMinutes(-5) <= DateTime.Now
|
||||
&& DateTime.Now <= EndTime; //.AddMinutes(-5);
|
||||
}
|
||||
}
|
||||
//public string ConferenceNumberToDial { get; set; }
|
||||
public string ConferencePassword { get; set; }
|
||||
public bool IsOneButtonToPushMeeting { get; set; }
|
||||
|
||||
public List<Call> Calls { get; private set; }
|
||||
|
||||
public Meeting()
|
||||
{
|
||||
Calls = new List<Call>();
|
||||
}
|
||||
}
|
||||
|
||||
public class Call
|
||||
{
|
||||
public string Number { get; set; }
|
||||
public string Protocol { get; set; }
|
||||
public string CallRate { get; set; }
|
||||
public string CallType { get; set; }
|
||||
}
|
||||
|
||||
public class MeetingEventArgs : EventArgs
|
||||
{
|
||||
public eMeetingEventChangeType ChangeType { get; set; }
|
||||
public Meeting Meeting { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace PepperDash.Essentials.Core.Devices.AudioCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a common set of data about a codec
|
||||
/// </summary>
|
||||
public interface IAudioCodecInfo
|
||||
{
|
||||
AudioCodecInfo CodecInfo { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores general information about a codec
|
||||
/// </summary>
|
||||
public abstract class AudioCodecInfo
|
||||
{
|
||||
public abstract string PhoneNumber { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace PepperDash.Essentials.Core.Devices.AudioCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// For rooms that have audio codec
|
||||
/// </summary>
|
||||
public interface IHasAudioCodec
|
||||
{
|
||||
AudioCodecBase AudioCodec { get; }
|
||||
BoolFeedback InCallFeedback { get; }
|
||||
|
||||
///// <summary>
|
||||
///// Make this more specific
|
||||
///// </summary>
|
||||
//List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem> ActiveCalls { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Core.VideoCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the required elements for layout control
|
||||
/// </summary>
|
||||
public interface IHasCodecLayouts
|
||||
{
|
||||
StringFeedback LocalLayoutFeedback { get; }
|
||||
|
||||
void LocalLayoutToggle();
|
||||
void LocalLayoutToggleSingleProminent();
|
||||
void MinMaxLayoutToggle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Core.VideoCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the requred elements for selfview control
|
||||
/// </summary>
|
||||
public interface IHasCodecSelfView
|
||||
{
|
||||
BoolFeedback SelfviewIsOnFeedback { get; }
|
||||
|
||||
bool ShowSelfViewByDefault { get; }
|
||||
|
||||
void SelfViewModeOn();
|
||||
|
||||
void SelfViewModeOff();
|
||||
|
||||
void SelfViewModeToggle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace PepperDash.Essentials.Core.Devices.VideoCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// For rooms that have video codec
|
||||
/// </summary>
|
||||
public interface IHasVideoCodec
|
||||
{
|
||||
VideoCodecBase VideoCodec { get; }
|
||||
BoolFeedback InCallFeedback { get; }
|
||||
|
||||
///// <summary>
|
||||
///// Make this more specific
|
||||
///// </summary>
|
||||
//List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem> ActiveCalls { get; }
|
||||
|
||||
/// <summary>
|
||||
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||
/// </summary>
|
||||
IntFeedback CallTypeFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
BoolFeedback PrivacyModeIsOnFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// When something in the room is sharing with the far end or through other means
|
||||
/// </summary>
|
||||
BoolFeedback IsSharingFeedback { get; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a common set of data about a codec
|
||||
/// </summary>
|
||||
public interface iVideoCodecInfo
|
||||
{
|
||||
VideoCodecInfo CodecInfo { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores general information about a codec
|
||||
/// </summary>
|
||||
public abstract class VideoCodecInfo
|
||||
{
|
||||
public abstract bool MultiSiteOptionIsEnabled { get; }
|
||||
public abstract string IpAddress { get; }
|
||||
public abstract string SipPhoneNumber { get; }
|
||||
public abstract string E164Alias { get; }
|
||||
public abstract string H323Id { get; }
|
||||
public abstract string SipUri { get; }
|
||||
public abstract bool AutoAnswerEnabled { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices.AudioCodec
|
||||
{
|
||||
public abstract class AudioCodecBase : EssentialsDevice, IHasDialer, IUsageTracking, IAudioCodecInfo
|
||||
{
|
||||
|
||||
public event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
|
||||
|
||||
public AudioCodecInfo CodecInfo { get; protected set; }
|
||||
|
||||
#region IUsageTracking Members
|
||||
|
||||
/// <summary>
|
||||
/// This object can be added by outside users of this class to provide usage tracking
|
||||
/// for various services
|
||||
/// </summary>
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns true when any call is not in state Unknown, Disconnecting, Disconnected
|
||||
/// </summary>
|
||||
public bool IsInCall
|
||||
{
|
||||
get
|
||||
{
|
||||
bool value;
|
||||
|
||||
if (ActiveCalls != null)
|
||||
value = ActiveCalls.Any(c => c.IsActiveCall);
|
||||
else
|
||||
value = false;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// In most cases only a single call can be active
|
||||
public List<CodecActiveCallItem> ActiveCalls { get; set; }
|
||||
|
||||
public AudioCodecBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
ActiveCalls = new List<CodecActiveCallItem>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to fire CallStatusChange event with old and new status
|
||||
/// </summary>
|
||||
protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call)
|
||||
{
|
||||
call.Status = newStatus;
|
||||
|
||||
OnCallStatusChange(call);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="previousStatus"></param>
|
||||
/// <param name="newStatus"></param>
|
||||
/// <param name="item"></param>
|
||||
protected void OnCallStatusChange(CodecActiveCallItem item)
|
||||
{
|
||||
var handler = CallStatusChange;
|
||||
if (handler != null)
|
||||
handler(this, new CodecCallStatusItemChangeEventArgs(item));
|
||||
|
||||
if (UsageTracker != null)
|
||||
{
|
||||
if (IsInCall && !UsageTracker.UsageTrackingStarted)
|
||||
UsageTracker.StartDeviceUsage();
|
||||
else if (UsageTracker.UsageTrackingStarted && !IsInCall)
|
||||
UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
|
||||
#region IHasDialer Members
|
||||
|
||||
public abstract void Dial(string number);
|
||||
|
||||
public abstract void EndCall(CodecActiveCallItem activeCall);
|
||||
|
||||
public abstract void EndAllCalls();
|
||||
|
||||
public abstract void AcceptCall(CodecActiveCallItem item);
|
||||
|
||||
public abstract void RejectCall(CodecActiveCallItem item);
|
||||
|
||||
public abstract void SendDtmf(string digit);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
|
||||
var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
|
||||
string description = descriptionAttribute[0].Description;
|
||||
string description = descriptionAttribute[0].Description;
|
||||
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
|
||||
DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice);
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices.VideoCodec
|
||||
{
|
||||
public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs,
|
||||
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Fires when the status of any active, dialing, or incoming call changes or is new
|
||||
/// </summary>
|
||||
public event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
|
||||
|
||||
public event EventHandler<EventArgs> IsReadyChange;
|
||||
|
||||
public IBasicCommunication Communication { get; protected set; }
|
||||
|
||||
#region IUsageTracking Members
|
||||
|
||||
/// <summary>
|
||||
/// This object can be added by outside users of this class to provide usage tracking
|
||||
/// for various services
|
||||
/// </summary>
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// An internal pseudo-source that is routable and connected to the osd input
|
||||
/// </summary>
|
||||
public DummyRoutingInputsDevice OsdSource { get; protected set; }
|
||||
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true when any call is not in state Unknown, Disconnecting, Disconnected
|
||||
/// </summary>
|
||||
public bool IsInCall
|
||||
{
|
||||
get
|
||||
{
|
||||
bool value;
|
||||
|
||||
if (ActiveCalls != null)
|
||||
value = ActiveCalls.Any(c => c.IsActiveCall);
|
||||
else
|
||||
value = false;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public BoolFeedback StandbyIsOnFeedback { get; private set; }
|
||||
|
||||
abstract protected Func<bool> PrivacyModeIsOnFeedbackFunc { get; }
|
||||
abstract protected Func<int> VolumeLevelFeedbackFunc { get; }
|
||||
abstract protected Func<bool> MuteFeedbackFunc { get; }
|
||||
abstract protected Func<bool> StandbyIsOnFeedbackFunc { get; }
|
||||
|
||||
public List<CodecActiveCallItem> ActiveCalls { get; set; }
|
||||
|
||||
public VideoCodecInfo CodecInfo { get; protected set; }
|
||||
|
||||
public bool ShowSelfViewByDefault { get; protected set; }
|
||||
|
||||
|
||||
public bool IsReady { get; protected set; }
|
||||
|
||||
public 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<RoutingInputPort>();
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
|
||||
ActiveCalls = new List<CodecActiveCallItem>();
|
||||
}
|
||||
|
||||
#region IHasDialer Members
|
||||
|
||||
public abstract void Dial(string number);
|
||||
public abstract void Dial(Meeting meeting);
|
||||
public virtual void Dial(IInvitableContact contact)
|
||||
{
|
||||
|
||||
}
|
||||
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
|
||||
|
||||
public virtual List<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<Feedback>
|
||||
{
|
||||
PrivacyModeIsOnFeedback,
|
||||
SharingSourceFeedback
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ExecuteSwitch(object selector);
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to fire CallStatusChange event with old and new status
|
||||
/// </summary>
|
||||
protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call)
|
||||
{
|
||||
call.Status = newStatus;
|
||||
|
||||
OnCallStatusChange(call);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="previousStatus"></param>
|
||||
/// <param name="newStatus"></param>
|
||||
/// <param name="item"></param>
|
||||
protected 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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets IsReady property and fires the event. Used for dependent classes to sync up their data.
|
||||
/// </summary>
|
||||
protected void SetIsReady()
|
||||
{
|
||||
IsReady = true;
|
||||
var h = IsReadyChange;
|
||||
if(h != null)
|
||||
h(this, new EventArgs());
|
||||
}
|
||||
|
||||
#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 IHasSharing 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; }
|
||||
|
||||
abstract protected Func<string> SharingSourceFeedbackFunc { get; }
|
||||
abstract protected Func<bool> SharingContentIsOnFeedbackFunc { get; }
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
// **** DEBUGGING THINGS ****
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used to track the status of syncronizing the phonebook values when connecting to a codec or refreshing the phonebook info
|
||||
/// </summary>
|
||||
public class CodecPhonebookSyncState : IKeyed
|
||||
{
|
||||
bool _InitialSyncComplete;
|
||||
|
||||
public event EventHandler<EventArgs> InitialSyncCompleted;
|
||||
|
||||
public string Key { get; private set; }
|
||||
|
||||
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; }
|
||||
|
||||
public CodecPhonebookSyncState(string key)
|
||||
{
|
||||
Key = key;
|
||||
|
||||
CodecDisconnected();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void CheckSyncStatus()
|
||||
{
|
||||
if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved)
|
||||
{
|
||||
InitialSyncComplete = true;
|
||||
Debug.Console(1, this, "Initial Phonebook Sync Complete!");
|
||||
}
|
||||
else
|
||||
InitialSyncComplete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Devices
|
||||
{
|
||||
public class DestinationListItem
|
||||
{
|
||||
[JsonProperty("sinkKey")]
|
||||
public string SinkKey { get; set; }
|
||||
|
||||
private EssentialsDevice _sinkDevice;
|
||||
|
||||
[JsonIgnore]
|
||||
public EssentialsDevice SinkDevice
|
||||
{
|
||||
get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as EssentialsDevice); }
|
||||
}
|
||||
|
||||
public string PreferredName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
return SinkDevice == null ? "---" : SinkDevice.Name;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("includeInDestinationList")]
|
||||
public bool IncludeInDestinationList { get; set; }
|
||||
|
||||
[JsonProperty("order")]
|
||||
public int Order { get; set; }
|
||||
|
||||
[JsonProperty("surfaceLocation")]
|
||||
public int SurfaceLocation { get; set; }
|
||||
|
||||
[JsonProperty("verticalLocation")]
|
||||
public int VerticalLocation { get; set; }
|
||||
|
||||
[JsonProperty("horizontalLocation")]
|
||||
public int HorizontalLocation { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,21 +2,21 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public interface IBasicVideoMute
|
||||
{
|
||||
void VideoMuteToggle();
|
||||
}
|
||||
|
||||
public interface IBasicVideoMuteWithFeedback : IBasicVideoMute
|
||||
{
|
||||
BoolFeedback VideoMuteIsOn { get; }
|
||||
|
||||
void VideoMuteOn();
|
||||
void VideoMuteOff();
|
||||
|
||||
}
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public interface IBasicVideoMute
|
||||
{
|
||||
void VideoMuteToggle();
|
||||
}
|
||||
|
||||
public interface IBasicVideoMuteWithFeedback : IBasicVideoMute
|
||||
{
|
||||
BoolFeedback VideoMuteIsOn { get; }
|
||||
|
||||
void VideoMuteOn();
|
||||
void VideoMuteOff();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
@@ -31,16 +24,11 @@ namespace PepperDash.Essentials.Core
|
||||
/// Returns the source Device for this, if it exists in DeviceManager
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public Device SourceDevice
|
||||
public EssentialsDevice SourceDevice
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_SourceDevice == null)
|
||||
_SourceDevice = DeviceManager.GetDeviceForKey(SourceKey) as Device;
|
||||
return _SourceDevice;
|
||||
}
|
||||
get { return _sourceDevice ?? (_sourceDevice = DeviceManager.GetDeviceForKey(SourceKey) as EssentialsDevice); }
|
||||
}
|
||||
Device _SourceDevice;
|
||||
private EssentialsDevice _sourceDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the source's Name or this AlternateName property, if
|
||||
@@ -51,13 +39,12 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(Name))
|
||||
{
|
||||
if (SourceDevice == null)
|
||||
return "---";
|
||||
return SourceDevice.Name;
|
||||
}
|
||||
return Name;
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
return SourceDevice == null ? "---" : SourceDevice.Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
public class EssentialsDualDisplayFusionController:EssentialsHuddleVtc1FusionController
|
||||
{
|
||||
private readonly EssentialsDualDisplayRoom _room;
|
||||
|
||||
public EssentialsDualDisplayFusionController(EssentialsDualDisplayRoom room, uint ipId) : base(room, ipId)
|
||||
{
|
||||
_room = room;
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsHuddleVtc1FusionController
|
||||
|
||||
protected override void ExecuteCustomSteps()
|
||||
{
|
||||
SetUpDisplays();
|
||||
base.ExecuteCustomSteps();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void SetUpDisplays()
|
||||
{
|
||||
if (_room == null) return;
|
||||
|
||||
var leftDisplay = _room.LeftDisplay as DisplayBase;
|
||||
var rightDisplay = _room.RightDisplay as DisplayBase;
|
||||
|
||||
SetUpDisplay(leftDisplay);
|
||||
SetUpDisplay(rightDisplay);
|
||||
}
|
||||
|
||||
protected override void SetUpDefaultDisplay()
|
||||
{
|
||||
Debug.Console(0, this, "No default display for Dual Display Room");
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsFusionSystemControllerBase
|
||||
|
||||
protected override void SetUpDefaultDisplayAsset()
|
||||
{
|
||||
Debug.Console(0, this, "No default display for Dual Display Room");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void SetUpDisplay(DisplayBase display)
|
||||
{
|
||||
FusionAsset tempAsset;
|
||||
|
||||
display.UsageTracker = new UsageTracking(display){UsageIsTracked = true};
|
||||
display.UsageTracker.DeviceUsageEnded += UsageTrackerOnDeviceUsageEnded;
|
||||
|
||||
var config = ConfigReader.ConfigObject.Devices.SingleOrDefault(d => d.Key == display.Key);
|
||||
|
||||
if (!FusionStaticAssets.TryGetValue(config.Uid, out tempAsset))
|
||||
{
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), display.Name,
|
||||
"Display", "");
|
||||
FusionStaticAssets.Add(config.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var displayAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
|
||||
tempAsset.InstanceId);
|
||||
|
||||
displayAsset.PowerOn.OutputSig.UserObject = new Action<bool>(b => { if (b) display.PowerOn(); });
|
||||
displayAsset.PowerOff.OutputSig.UserObject = new Action<bool>(b => { if (b) display.PowerOff(); });
|
||||
|
||||
if (!(display is ICommunicationMonitor))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var displayCommMonitor = display as ICommunicationMonitor;
|
||||
|
||||
displayAsset.Connected.InputSig.BoolValue = displayCommMonitor.CommunicationMonitor.Status ==
|
||||
MonitorStatus.IsOk;
|
||||
displayCommMonitor.CommunicationMonitor.StatusChange += (o, a) =>
|
||||
{
|
||||
displayAsset.Connected.InputSig.BoolValue = displayCommMonitor.CommunicationMonitor.Status ==
|
||||
MonitorStatus.IsOk;
|
||||
};
|
||||
}
|
||||
|
||||
private void UsageTrackerOnDeviceUsageEnded(object sender, DeviceUsageEventArgs deviceUsageEventArgs)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Fusion
|
||||
{
|
||||
public class EssentialsHuddleSpaceFusionController:EssentialsFusionSystemControllerBase
|
||||
{
|
||||
private EssentialsHuddleSpaceRoom _room;
|
||||
|
||||
public EssentialsHuddleSpaceFusionController(EssentialsHuddleSpaceRoom room, uint ipId) : base(room, ipId)
|
||||
{
|
||||
_room = room;
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharpPro;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
public class EssentialsHuddleVtc1FusionController : EssentialsFusionSystemControllerBase
|
||||
{
|
||||
private readonly EssentialsHuddleVtc1Room _room;
|
||||
private BooleanSigData _codecIsInCall;
|
||||
|
||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
|
||||
: base(room, ipId)
|
||||
{
|
||||
_room = room;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called in base class constructor before RVI and GUID files are built
|
||||
/// </summary>
|
||||
protected override void ExecuteCustomSteps()
|
||||
{
|
||||
SetUpCodec();
|
||||
base.ExecuteCustomSteps();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a static asset for the codec and maps the joins to the main room symbol
|
||||
/// </summary>
|
||||
private void SetUpCodec()
|
||||
{
|
||||
try
|
||||
{
|
||||
var codec = _room.VideoCodec;
|
||||
|
||||
if (codec == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
|
||||
return;
|
||||
}
|
||||
|
||||
codec.UsageTracker = new UsageTracking(codec) {UsageIsTracked = true};
|
||||
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||
|
||||
var codecPowerOnAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
codec.StandbyDeactivate();
|
||||
}
|
||||
});
|
||||
var codecPowerOffAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
codec.StandbyActivate();
|
||||
}
|
||||
});
|
||||
|
||||
// Map FusionRoom Attributes:
|
||||
|
||||
// Codec volume
|
||||
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
|
||||
codecVolume.OutputSig.UserObject =
|
||||
new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
|
||||
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
|
||||
|
||||
// In Call Status
|
||||
_codecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
|
||||
codec.CallStatusChange += codec_CallStatusChange;
|
||||
|
||||
// Online status
|
||||
if (codec is ICommunicationMonitor)
|
||||
{
|
||||
var c = codec as ICommunicationMonitor;
|
||||
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
|
||||
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
|
||||
c.CommunicationMonitor.StatusChange +=
|
||||
(o, a) => { codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; };
|
||||
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key,
|
||||
"Online - VC 1");
|
||||
}
|
||||
|
||||
// Codec IP Address
|
||||
var codecHasIpInfo = false;
|
||||
var codecComm = codec.Communication;
|
||||
|
||||
var codecIpAddress = string.Empty;
|
||||
var codecIpPort = 0;
|
||||
|
||||
if (codecComm is GenericSshClient)
|
||||
{
|
||||
codecIpAddress = (codecComm as GenericSshClient).Hostname;
|
||||
codecIpPort = (codecComm as GenericSshClient).Port;
|
||||
codecHasIpInfo = true;
|
||||
}
|
||||
else if (codecComm is GenericTcpIpClient)
|
||||
{
|
||||
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
|
||||
codecIpPort = (codecComm as GenericTcpIpClient).Port;
|
||||
codecHasIpInfo = true;
|
||||
}
|
||||
|
||||
if (codecHasIpInfo)
|
||||
{
|
||||
var codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC",
|
||||
eSigIoMask.InputSigOnly);
|
||||
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
|
||||
|
||||
var codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC",
|
||||
eSigIoMask.InputSigOnly);
|
||||
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
|
||||
}
|
||||
|
||||
FusionAsset tempAsset;
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
|
||||
|
||||
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||
{
|
||||
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new asset
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name,
|
||||
"Codec", "");
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
|
||||
tempAsset.InstanceId);
|
||||
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
|
||||
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
|
||||
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
|
||||
|
||||
// TODO: Map relevant attributes on asset symbol
|
||||
|
||||
codecAsset.TrySetMakeModel(codec);
|
||||
codecAsset.TryLinkAssetErrorToCommunication(codec);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void codec_CallStatusChange(object sender, Devices.Codec.CodecCallStatusItemChangeEventArgs e)
|
||||
{
|
||||
var codec = _room.VideoCodec;
|
||||
|
||||
_codecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Rooms;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
@@ -40,43 +41,43 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
var devProps = JsonConvert.DeserializeObject<RoomOnToDefaultSourceWhenOccupiedConfig>(deviceConfig.Properties.ToString());
|
||||
|
||||
var enableFeature = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupied"));
|
||||
var enableFeature = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupied"));
|
||||
if (enableFeature != null)
|
||||
devProps.EnableRoomOnWhenOccupied = bool.Parse(enableFeature.CustomFieldValue);
|
||||
|
||||
var enableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomOnWhenOccupiedStartTime"));
|
||||
var enableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("RoomOnWhenOccupiedStartTime"));
|
||||
if (enableTime != null)
|
||||
devProps.OccupancyStartTime = enableTime.CustomFieldValue;
|
||||
|
||||
var disableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomOnWhenOccupiedEndTime"));
|
||||
var disableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("RoomOnWhenOccupiedEndTime"));
|
||||
if (disableTime != null)
|
||||
devProps.OccupancyEndTime = disableTime.CustomFieldValue;
|
||||
|
||||
var enableSunday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedSun"));
|
||||
var enableSunday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedSun"));
|
||||
if (enableSunday != null)
|
||||
devProps.EnableSunday = bool.Parse(enableSunday.CustomFieldValue);
|
||||
|
||||
var enableMonday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedMon"));
|
||||
var enableMonday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedMon"));
|
||||
if (enableMonday != null)
|
||||
devProps.EnableMonday = bool.Parse(enableMonday.CustomFieldValue);
|
||||
|
||||
var enableTuesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedTue"));
|
||||
var enableTuesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedTue"));
|
||||
if (enableTuesday != null)
|
||||
devProps.EnableTuesday = bool.Parse(enableTuesday.CustomFieldValue);
|
||||
|
||||
var enableWednesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedWed"));
|
||||
var enableWednesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedWed"));
|
||||
if (enableWednesday != null)
|
||||
devProps.EnableWednesday = bool.Parse(enableWednesday.CustomFieldValue);
|
||||
|
||||
var enableThursday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedThu"));
|
||||
var enableThursday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedThu"));
|
||||
if (enableThursday != null)
|
||||
devProps.EnableThursday = bool.Parse(enableThursday.CustomFieldValue);
|
||||
|
||||
var enableFriday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedFri"));
|
||||
var enableFriday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedFri"));
|
||||
if (enableFriday != null)
|
||||
devProps.EnableFriday = bool.Parse(enableFriday.CustomFieldValue);
|
||||
|
||||
var enableSaturday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedSat"));
|
||||
var enableSaturday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedSat"));
|
||||
if (enableSaturday != null)
|
||||
devProps.EnableSaturday = bool.Parse(enableSaturday.CustomFieldValue);
|
||||
|
||||
@@ -95,7 +96,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
|
||||
// Set the help message
|
||||
var helpMessage = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomHelpMessage"));
|
||||
var helpMessage = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("RoomHelpMessage"));
|
||||
if (helpMessage != null)
|
||||
{
|
||||
//Debug.Console(1, "Current Help Message: {0}. New Help Message: {1}", deviceConfig.Properties["help"]["message"].Value<string>(ToString()), helpMessage.CustomFieldValue);
|
||||
|
||||
@@ -182,17 +182,38 @@
|
||||
<Compile Include="Crestron IO\Relay\GenericRelayDevice.cs" />
|
||||
<Compile Include="Crestron IO\Relay\ISwitchedOutput.cs" />
|
||||
<Compile Include="Crestron IO\StatusSign\StatusSignController.cs" />
|
||||
<Compile Include="Devices\CodecInterfaces.cs" />
|
||||
<Compile Include="Devices\Base Classes\AudioCodecBase.cs" />
|
||||
<Compile Include="Devices\Interfaces\CodecInterfaces.cs" />
|
||||
<Compile Include="Devices\CrestronProcessor.cs" />
|
||||
<Compile Include="Devices\DeviceApiBase.cs" />
|
||||
<Compile Include="Devices\DestinationListItem.cs" />
|
||||
<Compile Include="Devices\Base Classes\DeviceApiBase.cs" />
|
||||
<Compile Include="Devices\DeviceFeedbackExtensions.cs" />
|
||||
<Compile Include="Devices\EssentialsBridgeableDevice.cs" />
|
||||
<Compile Include="Devices\EssentialsDevice.cs" />
|
||||
<Compile Include="Devices\IProjectorInterfaces.cs" />
|
||||
<Compile Include="Devices\Base Classes\EssentialsBridgeableDevice.cs" />
|
||||
<Compile Include="Devices\Base Classes\EssentialsDevice.cs" />
|
||||
<Compile Include="Devices\Interfaces\IProjectorInterfaces.cs" />
|
||||
<Compile Include="Devices\PC\InRoomPc.cs" />
|
||||
<Compile Include="Devices\PC\Laptop.cs" />
|
||||
<Compile Include="Devices\ReconfigurableDevice.cs" />
|
||||
<Compile Include="Devices\Base Classes\ReconfigurableDevice.cs" />
|
||||
<Compile Include="Devices\Base Classes\VideoCodecBase.cs" />
|
||||
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\CodecActiveCallItem.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\eCodecCallDirection.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\eCodecCallStatus.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\eCodecCallType.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\eMeetingPrivacy.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IAudioCodecInfo.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\iCodecAudio.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasAudioCodec.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\iHasCallFavorites.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\iHasCallHistory.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasCodecLayouts.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasCodecSelfview.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\iHasContentSharing.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\iHasDialer.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\iHasDirectory.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\iHasScheduleAwareness.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasVideoCodec.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\iVideoCodecInfo.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IMobileControl.cs" />
|
||||
<Compile Include="Factory\DeviceFactory.cs" />
|
||||
<Compile Include="Factory\IDeviceFactory.cs" />
|
||||
@@ -203,7 +224,10 @@
|
||||
<Compile Include="Feedbacks\IntFeedback.cs" />
|
||||
<Compile Include="Feedbacks\SerialFeedback.cs" />
|
||||
<Compile Include="Feedbacks\StringFeedback.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" />
|
||||
<Compile Include="Fusion\EssentialsDualDisplayFusionController.cs" />
|
||||
<Compile Include="Fusion\EssentialsFusionSystemControllerBase.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleSpaceFusionController.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleVtc1FusionController.cs" />
|
||||
<Compile Include="Fusion\FusionCustomPropertiesBridge.cs" />
|
||||
<Compile Include="Fusion\FusionEventHandlers.cs" />
|
||||
<Compile Include="Fusion\FusionProcessorQueries.cs" />
|
||||
@@ -232,8 +256,8 @@
|
||||
<Compile Include="Config\InfoConfig.cs" />
|
||||
<Compile Include="Config\DeviceConfig.cs" />
|
||||
<Compile Include="Devices\DisplayUiConstants.cs" />
|
||||
<Compile Include="Devices\IUsageTracking.cs" />
|
||||
<Compile Include="Devices\DeviceJsonApi.cs" />
|
||||
<Compile Include="Devices\Interfaces\IUsageTracking.cs" />
|
||||
<Compile Include="Devices\Base Classes\DeviceJsonApi.cs" />
|
||||
<Compile Include="Devices\SourceListItem.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IDisplayBasic.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IDumbSource.cs" />
|
||||
@@ -250,7 +274,7 @@
|
||||
<Compile Include="DeviceTypeInterfaces\ITransport.cs" />
|
||||
<Compile Include="Devices\GenericMonitoredTcpDevice.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\INumeric.cs" />
|
||||
<Compile Include="Devices\IVolumeAndAudioInterfaces.cs" />
|
||||
<Compile Include="Devices\Interfaces\IVolumeAndAudioInterfaces.cs" />
|
||||
<Compile Include="Display\BasicIrDisplay.cs" />
|
||||
<Compile Include="Feedbacks\BoolFeedbackOneShot.cs" />
|
||||
<Compile Include="Ramps and Increments\NumericalHelpers.cs" />
|
||||
@@ -258,10 +282,24 @@
|
||||
<Compile Include="Remotes\ButtonExtensions.cs" />
|
||||
<Compile Include="Remotes\CrestronRemotePropertiesConfig.cs" />
|
||||
<Compile Include="Remotes\Hrxx0WirelessRemoteController.cs" />
|
||||
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
|
||||
<Compile Include="Room\EssentialsRoomBase.cs" />
|
||||
<Compile Include="Room\Interfaces.cs" />
|
||||
<Compile Include="Room\iOccupancyStatusProvider.cs" />
|
||||
<Compile Include="Rooms\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
|
||||
<Compile Include="Rooms\Config\DDVC01RoomPropertiesConfig.cs" />
|
||||
<Compile Include="Rooms\Config\EssentialsDualDisplayRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Rooms\Config\EssentialsHuddleRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Rooms\Config\EssentialsHuddleVtc1PropertiesConfig.cs" />
|
||||
<Compile Include="Rooms\Config\EssentialsNDisplayRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Rooms\Config\EssentialsPresentationPropertiesConfig.cs" />
|
||||
<Compile Include="Rooms\Config\EssentialsVolumeLevelConfig.cs" />
|
||||
<Compile Include="Rooms\Emergency\EsentialsRoomEmergencyContactClosure.cs" />
|
||||
<Compile Include="Rooms\EssentialsRoomBase.cs" />
|
||||
<Compile Include="Rooms\Config\EssentialsRoomConfig.cs" />
|
||||
<Compile Include="Rooms\Config\EssentialsRoomEmergencyConfig.cs" />
|
||||
<Compile Include="Rooms\Interfaces.cs" />
|
||||
<Compile Include="Rooms\iOccupancyStatusProvider.cs" />
|
||||
<Compile Include="Rooms\Types\EssentialsDualDisplayRoom.cs" />
|
||||
<Compile Include="Rooms\Types\EssentialsHuddleSpaceRoom.cs" />
|
||||
<Compile Include="Rooms\Types\EssentialsHuddleVtc1Room.cs" />
|
||||
<Compile Include="Rooms\Types\EssentialsNDisplayRoomBase.cs" />
|
||||
<Compile Include="Routing\DummyRoutingInputsDevice.cs" />
|
||||
<Compile Include="Routing\ICardPortsDevice.cs" />
|
||||
<Compile Include="InUseTracking\IInUseTracking.cs" />
|
||||
@@ -272,10 +310,10 @@
|
||||
<Compile Include="Monitoring\StatusMonitorBase.cs" />
|
||||
<Compile Include="Monitoring\Interfaces.cs" />
|
||||
<Compile Include="Monitoring\GenericCommunicationMonitor.cs" />
|
||||
<Compile Include="Devices\AudioInterfaces.cs" />
|
||||
<Compile Include="Devices\IAttachVideoStatusExtensions.cs" />
|
||||
<Compile Include="Devices\IHasFeedbacks.cs" />
|
||||
<Compile Include="Devices\SmartObjectBaseTypes.cs" />
|
||||
<Compile Include="Devices\Interfaces\AudioInterfaces.cs" />
|
||||
<Compile Include="Devices\Interfaces\IAttachVideoStatusExtensions.cs" />
|
||||
<Compile Include="Devices\Interfaces\IHasFeedbacks.cs" />
|
||||
<Compile Include="Devices\Base Classes\SmartObjectBaseTypes.cs" />
|
||||
<Compile Include="Devices\PresentationDeviceType.cs" />
|
||||
<Compile Include="Display\MockDisplay.cs" />
|
||||
<Compile Include="Ethernet\EthernetStatistics.cs" />
|
||||
@@ -319,11 +357,11 @@
|
||||
<Compile Include="Devices\IrOutputPortController.cs" />
|
||||
<Compile Include="Display\DisplayBase.cs" />
|
||||
<Compile Include="Feedbacks\FeedbackBase.cs" />
|
||||
<Compile Include="Room\Room.cs" />
|
||||
<Compile Include="Rooms\Room.cs" />
|
||||
<Compile Include="SmartObjects\SubpageReferencList\SourceListSubpageReferenceList.cs" />
|
||||
<Compile Include="Touchpanels\ModalDialog.cs" />
|
||||
<Compile Include="TriListBridges\HandlerBridge.cs" />
|
||||
<Compile Include="Devices\FIND HOMES Interfaces.cs" />
|
||||
<Compile Include="Devices\Interfaces\Interfaces.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SigHelper.cs" />
|
||||
<Compile Include="SmartObjects\SubpageReferencList\SubpageReferenceList.cs" />
|
||||
|
||||
@@ -1,315 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class EssentialsRoomBase : ReconfigurableDevice
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BoolFeedback OnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fires when the RoomOccupancy object is set
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> RoomOccupancyIsSet;
|
||||
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
public BoolFeedback IsCoolingDownFeedback { get; private set; }
|
||||
|
||||
public IOccupancyStatusProvider RoomOccupancy { get; private set; }
|
||||
|
||||
public bool OccupancyStatusProviderIsRemote { get; private set; }
|
||||
|
||||
protected abstract Func<bool> IsWarmingFeedbackFunc { get; }
|
||||
protected abstract Func<bool> IsCoolingFeedbackFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The config name of the source list
|
||||
/// </summary>
|
||||
public string SourceListKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timer used for informing the UIs of a shutdown
|
||||
/// </summary>
|
||||
public SecondsCountdownTimer ShutdownPromptTimer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int ShutdownPromptSeconds { get; set; }
|
||||
public int ShutdownVacancySeconds { get; set; }
|
||||
public eShutdownType ShutdownType { get; private set; }
|
||||
|
||||
public EssentialsRoomEmergencyBase Emergency { get; set; }
|
||||
|
||||
public Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; set; }
|
||||
|
||||
public string LogoUrl { get; set; }
|
||||
|
||||
protected SecondsCountdownTimer RoomVacancyShutdownTimer { get; private set; }
|
||||
|
||||
public eVacancyMode VacancyMode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Seconds after vacancy prompt is displayed until shutdown
|
||||
/// </summary>
|
||||
protected int RoomVacancyShutdownSeconds;
|
||||
|
||||
/// <summary>
|
||||
/// Seconds after vacancy detected until prompt is displayed
|
||||
/// </summary>
|
||||
protected int RoomVacancyShutdownPromptSeconds;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected abstract Func<bool> OnFeedbackFunc { get; }
|
||||
|
||||
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels = new Dictionary<IBasicVolumeWithFeedback, uint>();
|
||||
|
||||
/// <summary>
|
||||
/// When volume control devices change, should we zero the one that we are leaving?
|
||||
/// </summary>
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
|
||||
|
||||
|
||||
public EssentialsRoomBase(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
// Setup the ShutdownPromptTimer
|
||||
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
|
||||
ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!ShutdownPromptTimer.IsRunningFeedback.BoolValue)
|
||||
ShutdownType = eShutdownType.None;
|
||||
};
|
||||
ShutdownPromptTimer.HasFinished += (o, a) => Shutdown(); // Shutdown is triggered
|
||||
|
||||
ShutdownPromptSeconds = 60;
|
||||
ShutdownVacancySeconds = 120;
|
||||
|
||||
ShutdownType = eShutdownType.None;
|
||||
|
||||
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
|
||||
//RoomVacancyShutdownTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||
//{
|
||||
// if (!RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
|
||||
// ShutdownType = ShutdownType.Vacancy;
|
||||
//};
|
||||
RoomVacancyShutdownTimer.HasFinished += new EventHandler<EventArgs>(RoomVacancyShutdownPromptTimer_HasFinished); // Shutdown is triggered
|
||||
|
||||
RoomVacancyShutdownPromptSeconds = 1500; // 25 min to prompt warning
|
||||
RoomVacancyShutdownSeconds = 240; // 4 min after prompt will trigger shutdown prompt
|
||||
VacancyMode = eVacancyMode.None;
|
||||
|
||||
OnFeedback = new BoolFeedback(OnFeedbackFunc);
|
||||
|
||||
IsWarmingUpFeedback = new BoolFeedback(IsWarmingFeedbackFunc);
|
||||
IsCoolingDownFeedback = new BoolFeedback(IsCoolingFeedbackFunc);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
if (RoomOccupancy != null)
|
||||
OnRoomOccupancyIsSet();
|
||||
});
|
||||
}
|
||||
|
||||
void RoomVacancyShutdownPromptTimer_HasFinished(object sender, EventArgs e)
|
||||
{
|
||||
switch (VacancyMode)
|
||||
{
|
||||
case eVacancyMode.None:
|
||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||
break;
|
||||
case eVacancyMode.InInitialVacancy:
|
||||
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
|
||||
break;
|
||||
case eVacancyMode.InShutdownWarning:
|
||||
{
|
||||
StartShutdown(eShutdownType.Vacancy);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting Down due to vacancy.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
public void StartShutdown(eShutdownType type)
|
||||
{
|
||||
// Check for shutdowns running. Manual should override other shutdowns
|
||||
|
||||
if (type == eShutdownType.Manual)
|
||||
ShutdownPromptTimer.SecondsToCount = ShutdownPromptSeconds;
|
||||
else if (type == eShutdownType.Vacancy)
|
||||
ShutdownPromptTimer.SecondsToCount = ShutdownVacancySeconds;
|
||||
ShutdownType = type;
|
||||
ShutdownPromptTimer.Start();
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "ShutdownPromptTimer Started. Type: {0}. Seconds: {1}", ShutdownType, ShutdownPromptTimer.SecondsToCount);
|
||||
}
|
||||
|
||||
public void StartRoomVacancyTimer(eVacancyMode mode)
|
||||
{
|
||||
if (mode == eVacancyMode.None)
|
||||
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownPromptSeconds;
|
||||
else if (mode == eVacancyMode.InInitialVacancy)
|
||||
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds;
|
||||
else if (mode == eVacancyMode.InShutdownWarning)
|
||||
RoomVacancyShutdownTimer.SecondsToCount = 60;
|
||||
VacancyMode = mode;
|
||||
RoomVacancyShutdownTimer.Start();
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Vacancy Timer Started. Mode: {0}. Seconds: {1}", VacancyMode, RoomVacancyShutdownTimer.SecondsToCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the vacancy mode and shutsdwon the room
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
VacancyMode = eVacancyMode.None;
|
||||
EndShutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is for the derived class to define it's specific shutdown
|
||||
/// requirements but should not be called directly. It is called by Shutdown()
|
||||
/// </summary>
|
||||
protected abstract void EndShutdown();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Override this to implement a default volume level(s) method
|
||||
/// </summary>
|
||||
public abstract void SetDefaultLevels();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the object to be used as the IOccupancyStatusProvider for the room. Can be an Occupancy Aggregator or a specific device
|
||||
/// </summary>
|
||||
/// <param name="statusProvider"></param>
|
||||
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
|
||||
{
|
||||
if (statusProvider == null)
|
||||
{
|
||||
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Room Occupancy set to device: '{0}'", (statusProvider as Device).Key);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Timeout Minutes from Config is: {0}", timeoutMinutes);
|
||||
|
||||
// If status provider is fusion, set flag to remote
|
||||
if (statusProvider is Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
|
||||
OccupancyStatusProviderIsRemote = true;
|
||||
|
||||
if(timeoutMinutes > 0)
|
||||
RoomVacancyShutdownSeconds = timeoutMinutes * 60;
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "RoomVacancyShutdownSeconds set to {0}", RoomVacancyShutdownSeconds);
|
||||
|
||||
RoomOccupancy = statusProvider;
|
||||
|
||||
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange -= RoomIsOccupiedFeedback_OutputChange;
|
||||
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
|
||||
|
||||
OnRoomOccupancyIsSet();
|
||||
}
|
||||
|
||||
void OnRoomOccupancyIsSet()
|
||||
{
|
||||
var handler = RoomOccupancyIsSet;
|
||||
if (handler != null)
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To allow base class to power room on to last source
|
||||
/// </summary>
|
||||
public abstract void PowerOnToDefaultOrLastSource();
|
||||
|
||||
/// <summary>
|
||||
/// To allow base class to power room on to default source
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool RunDefaultPresentRoute();
|
||||
|
||||
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Vacancy Detected");
|
||||
// Trigger the timer when the room is vacant
|
||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Occupancy Detected");
|
||||
// Reset the timer when the room is occupied
|
||||
RoomVacancyShutdownTimer.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
public abstract void RoomVacatedForTimeoutPeriod(object o);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To describe the various ways a room may be shutting down
|
||||
/// </summary>
|
||||
public enum eShutdownType
|
||||
{
|
||||
None = 0,
|
||||
External,
|
||||
Manual,
|
||||
Vacancy
|
||||
}
|
||||
|
||||
public enum eVacancyMode
|
||||
{
|
||||
None = 0,
|
||||
InInitialVacancy,
|
||||
InShutdownWarning
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum eWarmingCoolingMode
|
||||
{
|
||||
None,
|
||||
Warming,
|
||||
Cooling
|
||||
}
|
||||
|
||||
public abstract class EssentialsRoomEmergencyBase : IKeyed
|
||||
{
|
||||
public string Key { get; private set; }
|
||||
|
||||
public EssentialsRoomEmergencyBase(string key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
namespace PepperDash.Essentials.Core.Rooms
|
||||
{
|
||||
/// <summary>
|
||||
/// A device that when linked to a room can power the room on when enabled during scheduled hours.
|
||||
@@ -40,7 +33,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public EssentialsRoomBase Room { get; private set; }
|
||||
|
||||
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom;
|
||||
private Fusion.EssentialsFusionSystemControllerBase FusionRoom;
|
||||
|
||||
public RoomOnToDefaultSourceWhenOccupied(DeviceConfig config) :
|
||||
base (config)
|
||||
@@ -65,7 +58,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
var fusionRoomKey = PropertiesConfig.RoomKey + "-fusion";
|
||||
|
||||
FusionRoom = DeviceManager.GetDeviceForKey(fusionRoomKey) as Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase;
|
||||
FusionRoom = DeviceManager.GetDeviceForKey(fusionRoomKey) as Core.Fusion.EssentialsFusionSystemControllerBase;
|
||||
|
||||
if (FusionRoom == null)
|
||||
Debug.Console(1, this, "Unable to get Fusion Room from Device Manager with key: {0}", fusionRoomKey);
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Rooms.Config
|
||||
{
|
||||
public class DDVC01RoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig
|
||||
{
|
||||
[JsonProperty("roomPhoneNumber")]
|
||||
public string RoomPhoneNumber { get; set; }
|
||||
[JsonProperty("roomURI")]
|
||||
public string RoomURI { get; set; }
|
||||
[JsonProperty("speedDials")]
|
||||
public List<DDVC01SpeedDial> SpeedDials { get; set; }
|
||||
[JsonProperty("volumeSliderNames")]
|
||||
public List<string> VolumeSliderNames { get; set; }
|
||||
}
|
||||
|
||||
public class DDVC01SpeedDial
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty("number")]
|
||||
public string Number { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace PepperDash.Essentials.Core.Rooms.Config
|
||||
{
|
||||
public class EssentialsDualDisplayRoomPropertiesConfig : EssentialsNDisplayRoomPropertiesConfig
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Rooms.Config
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsHuddleRoomPropertiesConfig : EssentialsRoomPropertiesConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// The key of the default display device
|
||||
/// </summary>
|
||||
[JsonProperty("defaultDisplayKey")]
|
||||
public string DefaultDisplayKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The key of the default audio device
|
||||
/// </summary>
|
||||
[JsonProperty("defaultAudioKey")]
|
||||
public string DefaultAudioKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The key of the source list for the room
|
||||
/// </summary>
|
||||
[JsonProperty("sourceListKey")]
|
||||
public string SourceListKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The key of the default source item from the source list
|
||||
/// </summary>
|
||||
[JsonProperty("defaultSourceItem")]
|
||||
public string DefaultSourceItem { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Rooms.Config
|
||||
{
|
||||
public class EssentialsHuddleVtc1PropertiesConfig : EssentialsHuddleRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("videoCodecKey")]
|
||||
public string VideoCodecKey { get; set; }
|
||||
[JsonProperty("audioCodecKey")]
|
||||
public string AudioCodecKey { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Newtonsoft.Json.Converters;
|
||||
using PepperDash.Core;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Rooms.Config
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsNDisplayRoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig
|
||||
{
|
||||
[JsonProperty("defaultAudioBehavior")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public EAudioBehavior DefaultAudioBehavior { get; set; }
|
||||
[JsonProperty("defaultVideoBehavior")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public EVideoBehavior DefaultVideoBehavior { get; set; }
|
||||
[JsonProperty("destinationListKey")]
|
||||
public string DestinationListKey { get; set; }
|
||||
[JsonProperty("enableVideoBehaviorToggle")]
|
||||
public bool EnableVideoBehaviorToggle { get; set; }
|
||||
}
|
||||
|
||||
public class DisplayItem : IKeyName
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public enum EVideoBehavior
|
||||
{
|
||||
Basic,
|
||||
Advanced
|
||||
}
|
||||
|
||||
public enum EAudioBehavior
|
||||
{
|
||||
AudioFollowVideo,
|
||||
ChooseAudioFromDisplay,
|
||||
AudioFollowVideoWithDeroute
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Rooms.Config
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsPresentationRoomPropertiesConfig : EssentialsRoomPropertiesConfig
|
||||
{
|
||||
public string DefaultAudioBehavior { get; set; }
|
||||
public string DefaultAudioKey { get; set; }
|
||||
public string DefaultVideoBehavior { get; set; }
|
||||
public List<string> DisplayKeys { get; set; }
|
||||
public string SourceListKey { get; set; }
|
||||
public bool HasDsp { get; set; }
|
||||
|
||||
public EssentialsPresentationRoomPropertiesConfig()
|
||||
{
|
||||
DisplayKeys = new List<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Privacy;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Rooms.Config
|
||||
{
|
||||
public class EssentialsRoomConfigHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a room object from this config data
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Device GetRoomObject(DeviceConfig roomConfig)
|
||||
{
|
||||
var typeName = roomConfig.Type.ToLower();
|
||||
|
||||
if (typeName == "huddle")
|
||||
{
|
||||
var huddle = new EssentialsHuddleSpaceRoom(roomConfig);
|
||||
|
||||
return huddle;
|
||||
}
|
||||
if (typeName == "huddlevtc1")
|
||||
{
|
||||
EssentialsRoomBase rm = new EssentialsHuddleVtc1Room(roomConfig);
|
||||
|
||||
return rm;
|
||||
}
|
||||
if (typeName == "ddvc01Bridge")
|
||||
{
|
||||
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
|
||||
}
|
||||
|
||||
if (typeName != "dualdisplay")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var dualDisplay = new EssentialsDualDisplayRoom(roomConfig);
|
||||
return dualDisplay;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and operating, standalone emergegncy object that can be plugged into a room.
|
||||
/// Returns null if there is no emergency defined
|
||||
/// </summary>
|
||||
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, EssentialsRoomBase room)
|
||||
{
|
||||
// This emergency
|
||||
var emergency = props.Emergency;
|
||||
|
||||
if (emergency == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
//switch on emergency type here. Right now only contact and shutdown
|
||||
var e = new EssentialsRoomEmergencyContactClosure(room.Key + "-emergency", props.Emergency, room);
|
||||
DeviceManager.AddDevice(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="props"></param>
|
||||
/// <param name="room"></param>
|
||||
/// <returns></returns>
|
||||
public static MicrophonePrivacyController GetMicrophonePrivacy(
|
||||
EssentialsRoomPropertiesConfig props, IPrivacy room)
|
||||
{
|
||||
var microphonePrivacy = props.MicrophonePrivacy;
|
||||
if (microphonePrivacy == null)
|
||||
{
|
||||
Debug.Console(0, "Cannot create microphone privacy with null properties");
|
||||
return null;
|
||||
}
|
||||
// Get the MicrophonePrivacy device from the device manager
|
||||
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as
|
||||
MicrophonePrivacyController);
|
||||
// Set this room as the IPrivacy device
|
||||
if (mP == null)
|
||||
{
|
||||
Debug.Console(0, "ERROR: Selected device {0} is not MicrophonePrivacyController", props.MicrophonePrivacy.DeviceKey);
|
||||
return null;
|
||||
}
|
||||
mP.SetPrivacyDevice(room);
|
||||
|
||||
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
|
||||
|
||||
if (behaviour == null)
|
||||
{
|
||||
Debug.Console(0, "WARNING: No behaviour defined for MicrophonePrivacyController");
|
||||
return null;
|
||||
}
|
||||
switch (behaviour)
|
||||
{
|
||||
case "trackroomstate":
|
||||
{
|
||||
// Tie LED enable to room power state
|
||||
var essRoom = room as EssentialsRoomBase;
|
||||
if (essRoom != null)
|
||||
{
|
||||
essRoom.OnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
mP.EnableLeds = essRoom.OnFeedback.BoolValue;
|
||||
};
|
||||
|
||||
mP.EnableLeds = essRoom.OnFeedback.BoolValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "trackcallstate":
|
||||
{
|
||||
// Tie LED enable to room power state
|
||||
var inCallRoom = room as IHasInCallFeedback;
|
||||
if (inCallRoom != null)
|
||||
{
|
||||
inCallRoom.InCallFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
mP.EnableLeds = inCallRoom.InCallFeedback.BoolValue;
|
||||
};
|
||||
|
||||
mP.EnableLeds = inCallRoom.InCallFeedback.BoolValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return mP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("addresses")]
|
||||
public EssentialsRoomAddressPropertiesConfig Addresses { get; set; }
|
||||
|
||||
[JsonProperty("description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[JsonProperty("emergency")]
|
||||
public EssentialsRoomEmergencyConfig Emergency { get; set; }
|
||||
|
||||
[JsonProperty("help")]
|
||||
public EssentialsHelpPropertiesConfig Help { get; set; }
|
||||
|
||||
[JsonProperty("helpMessage")]
|
||||
public string HelpMessage { get; set; }
|
||||
|
||||
[JsonProperty("environment")]
|
||||
public EssentialsEnvironmentPropertiesConfig Environment { get; set; }
|
||||
|
||||
[JsonProperty("logo")]
|
||||
public EssentialsLogoPropertiesConfig Logo { get; set; }
|
||||
|
||||
[JsonProperty("microphonePrivacy")]
|
||||
public EssentialsRoomMicrophonePrivacyConfig MicrophonePrivacy { get; set; }
|
||||
|
||||
[JsonProperty("occupancy")]
|
||||
public EssentialsRoomOccSensorConfig Occupancy { get; set; }
|
||||
|
||||
[JsonProperty("oneButtonMeeting")]
|
||||
public EssentialsOneButtonMeetingPropertiesConfig OneButtonMeeting { get; set; }
|
||||
|
||||
[JsonProperty("shutdownVacancySeconds")]
|
||||
public int ShutdownVacancySeconds { get; set; }
|
||||
|
||||
[JsonProperty("shutdownPromptSeconds")]
|
||||
public int ShutdownPromptSeconds { get; set; }
|
||||
|
||||
[JsonProperty("tech")]
|
||||
public EssentialsRoomTechConfig Tech { get; set; }
|
||||
|
||||
[JsonProperty("volumes")]
|
||||
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
||||
|
||||
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
||||
}
|
||||
|
||||
public class EssentialsEnvironmentPropertiesConfig
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
[JsonProperty("deviceKeys")]
|
||||
public List<string> DeviceKeys { get; set; }
|
||||
|
||||
public EssentialsEnvironmentPropertiesConfig()
|
||||
{
|
||||
DeviceKeys = new List<string>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class EssentialsRoomMicrophonePrivacyConfig
|
||||
{
|
||||
[JsonProperty("deviceKey")]
|
||||
public string DeviceKey { get; set; }
|
||||
|
||||
[JsonProperty("behaviour")]
|
||||
public string Behaviour { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Properties for the help text box
|
||||
/// </summary>
|
||||
public class EssentialsHelpPropertiesConfig
|
||||
{
|
||||
[JsonProperty("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
[JsonProperty("showCallButton")]
|
||||
public bool ShowCallButton { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defaults to "Call Help Desk"
|
||||
/// </summary>
|
||||
[JsonProperty("callButtonText")]
|
||||
public string CallButtonText { get; set; }
|
||||
|
||||
public EssentialsHelpPropertiesConfig()
|
||||
{
|
||||
CallButtonText = "Call Help Desk";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsOneButtonMeetingPropertiesConfig
|
||||
{
|
||||
[JsonProperty("enable")]
|
||||
public bool Enable { get; set; }
|
||||
}
|
||||
|
||||
public class EssentialsRoomAddressPropertiesConfig
|
||||
{
|
||||
[JsonProperty("phoneNumber")]
|
||||
public string PhoneNumber { get; set; }
|
||||
|
||||
[JsonProperty("sipAddress")]
|
||||
public string SipAddress { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Properties for the room's logo on panels
|
||||
/// </summary>
|
||||
public class EssentialsLogoPropertiesConfig
|
||||
{
|
||||
[JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[JsonProperty("url")]
|
||||
public string Url { get; set; }
|
||||
/// <summary>
|
||||
/// Gets either the custom URL, a local-to-processor URL, or null if it's a default logo
|
||||
/// </summary>
|
||||
public string GetUrl()
|
||||
{
|
||||
if (Type == "url")
|
||||
return Url;
|
||||
if (Type == "system")
|
||||
return string.Format("http://{0}:8080/logo.png",
|
||||
CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents occupancy sensor(s) setup for a room
|
||||
/// </summary>
|
||||
public class EssentialsRoomOccSensorConfig
|
||||
{
|
||||
[JsonProperty("deviceKey")]
|
||||
public string DeviceKey { get; set; }
|
||||
|
||||
[JsonProperty("timeoutMinutes")]
|
||||
public int TimeoutMinutes { get; set; }
|
||||
}
|
||||
|
||||
public class EssentialsRoomTechConfig
|
||||
{
|
||||
[JsonProperty("password")]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace PepperDash.Essentials.Core.Rooms.Config
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsRoomEmergencyConfig
|
||||
{
|
||||
public EssentialsRoomEmergencyTriggerConfig Trigger { get; set; }
|
||||
|
||||
public string Behavior { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsRoomEmergencyTriggerConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// contact,
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
/// <summary>
|
||||
/// Input number if contact
|
||||
/// </summary>
|
||||
public int Number { get; set; }
|
||||
|
||||
public bool TriggerOnClose { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsRoomVolumesConfig
|
||||
{
|
||||
public EssentialsVolumeLevelConfig Master { get; set; }
|
||||
public EssentialsVolumeLevelConfig Program { get; set; }
|
||||
public EssentialsVolumeLevelConfig AudioCallRx { get; set; }
|
||||
public EssentialsVolumeLevelConfig AudioCallTx { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsVolumeLevelConfig
|
||||
{
|
||||
public string DeviceKey { get; set; }
|
||||
public string Label { get; set; }
|
||||
public int Level { get; set; }
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Helper to get the device associated with key - one timer.
|
||||
/// </summary>
|
||||
public IBasicVolumeWithFeedback GetDevice()
|
||||
{
|
||||
// DM output card format: deviceKey--output~number, dm8x8-1--output~4
|
||||
var match = Regex.Match(DeviceKey, @"([-_\w]+)--(\w+)~(\d+)");
|
||||
if (match.Success)
|
||||
{
|
||||
var devKey = match.Groups[1].Value;
|
||||
var chassis = DeviceManager.GetDeviceForKey(devKey) as DmChassisController;
|
||||
if (chassis != null)
|
||||
{
|
||||
var outputNum = Convert.ToUInt32(match.Groups[3].Value);
|
||||
if (chassis.VolumeControls.ContainsKey(outputNum)) // should always...
|
||||
return chassis.VolumeControls[outputNum];
|
||||
}
|
||||
// No volume for some reason. We have failed as developers
|
||||
return null;
|
||||
}
|
||||
|
||||
// DSP format: deviceKey--levelName, biampTesira-1--master
|
||||
match = Regex.Match(DeviceKey, @"([-_\w]+)--(.+)");
|
||||
if (match.Success)
|
||||
{
|
||||
var devKey = match.Groups[1].Value;
|
||||
var dsp = DeviceManager.GetDeviceForKey(devKey) as BiampTesiraForteDsp;
|
||||
if (dsp != null)
|
||||
{
|
||||
var levelTag = match.Groups[2].Value;
|
||||
if (dsp.LevelControlPoints.ContainsKey(levelTag)) // should always...
|
||||
return dsp.LevelControlPoints[levelTag];
|
||||
}
|
||||
// No volume for some reason. We have failed as developers
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using Crestron.SimplSharpPro;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Rooms
|
||||
{
|
||||
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
|
||||
{
|
||||
EssentialsRoomBase Room;
|
||||
string Behavior;
|
||||
bool TriggerOnClose;
|
||||
|
||||
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, EssentialsRoomBase room) :
|
||||
base(key)
|
||||
{
|
||||
Room = room;
|
||||
var cs = Global.ControlSystem;
|
||||
|
||||
if (config.Trigger.Type.Equals("contact", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var portNum = (uint)config.Trigger.Number;
|
||||
if (portNum <= cs.NumberOfDigitalInputPorts)
|
||||
{
|
||||
cs.DigitalInputPorts[portNum].Register();
|
||||
cs.DigitalInputPorts[portNum].StateChange += EsentialsRoomEmergencyContactClosure_StateChange;
|
||||
}
|
||||
}
|
||||
Behavior = config.Behavior;
|
||||
TriggerOnClose = config.Trigger.TriggerOnClose;
|
||||
}
|
||||
|
||||
void EsentialsRoomEmergencyContactClosure_StateChange(DigitalInput digitalInput, DigitalInputEventArgs args)
|
||||
{
|
||||
if (args.State && TriggerOnClose || !args.State && !TriggerOnClose)
|
||||
RunEmergencyBehavior();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void RunEmergencyBehavior()
|
||||
{
|
||||
if (Behavior.Equals("shutdown"))
|
||||
Room.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,810 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class EssentialsRoomBase : ReconfigurableDevice
|
||||
{
|
||||
protected EssentialsRoomPropertiesConfig BaseConfig;
|
||||
protected IBasicVolumeControls CurrentAudioDevice;
|
||||
protected Func<bool> IsCoolingFeedbackFunc;
|
||||
protected Func<bool> IsWarmingFeedbackFunc;
|
||||
protected string LastSourceKey;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected Func<bool> OnFeedbackFunc;
|
||||
|
||||
/// <summary>
|
||||
/// Seconds after vacancy detected until prompt is displayed
|
||||
/// </summary>
|
||||
protected int RoomVacancyShutdownPromptSeconds;
|
||||
|
||||
/// <summary>
|
||||
/// Seconds after vacancy prompt is displayed until shutdown
|
||||
/// </summary>
|
||||
protected int RoomVacancyShutdownSeconds;
|
||||
|
||||
protected CCriticalSection RoutingLock = new CCriticalSection();
|
||||
|
||||
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels =
|
||||
new Dictionary<IBasicVolumeWithFeedback, uint>();
|
||||
|
||||
private SourceListItem _currentSourceInfo;
|
||||
|
||||
/// <summary>
|
||||
/// If room is off, enables power on to last source. Default true
|
||||
/// </summary>
|
||||
public bool EnablePowerOnToLastSource { get; set; }
|
||||
|
||||
public const string DefaultSourceListKey = "default";
|
||||
|
||||
protected EssentialsRoomBase(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
BaseConfig = config.Properties.ToObject<EssentialsRoomPropertiesConfig>();
|
||||
|
||||
ZeroVolumeWhenSwtichingVolumeDevices = BaseConfig.ZeroVolumeWhenSwtichingVolumeDevices;
|
||||
SetupShutdownPrompt();
|
||||
|
||||
SetupRoomVacancyShutdown();
|
||||
|
||||
OnFeedback = new BoolFeedback(OnFeedbackFunc);
|
||||
|
||||
IsWarmingUpFeedback = new BoolFeedback(IsWarmingFeedbackFunc);
|
||||
IsCoolingDownFeedback = new BoolFeedback(IsCoolingFeedbackFunc);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
if (RoomOccupancy != null)
|
||||
{
|
||||
OnRoomOccupancyIsSet();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public IRoutingSinkWithSwitching DefaultDisplay { get; protected set; }
|
||||
public IRoutingSink DefaultAudioDevice { get; protected set; }
|
||||
public IBasicVolumeControls DefaultVolumeControls { get; protected set; }
|
||||
|
||||
public string DefaultSourceItem { get; set; }
|
||||
|
||||
public ushort DefaultVolume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
|
||||
/// tag to device.
|
||||
/// </summary>
|
||||
public IBasicVolumeControls CurrentVolumeControls
|
||||
{
|
||||
get { return CurrentAudioDevice; }
|
||||
set
|
||||
{
|
||||
if (value == CurrentAudioDevice)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var handler = CurrentVolumeDeviceChange;
|
||||
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this,
|
||||
new VolumeDeviceChangeEventArgs(CurrentAudioDevice, value, ChangeType.WillChange));
|
||||
}
|
||||
|
||||
var oldDevice = CurrentAudioDevice as IInUseTracking;
|
||||
var newDevice = value as IInUseTracking;
|
||||
|
||||
UpdateInUseTracking(oldDevice, newDevice);
|
||||
|
||||
CurrentAudioDevice = value;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(this,
|
||||
new VolumeDeviceChangeEventArgs(CurrentAudioDevice, value, ChangeType.DidChange));
|
||||
}
|
||||
}
|
||||
|
||||
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||
|
||||
public BoolFeedback OnFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
public BoolFeedback IsCoolingDownFeedback { get; private set; }
|
||||
|
||||
public IOccupancyStatusProvider RoomOccupancy { get; private set; }
|
||||
|
||||
public bool OccupancyStatusProviderIsRemote { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The config name of the source list
|
||||
/// </summary>
|
||||
public string SourceListKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timer used for informing the UIs of a shutdown
|
||||
/// </summary>
|
||||
public SecondsCountdownTimer ShutdownPromptTimer { get; private set; }
|
||||
|
||||
public int ShutdownPromptSeconds { get; set; }
|
||||
public int ShutdownVacancySeconds { get; set; }
|
||||
public eShutdownType ShutdownType { get; private set; }
|
||||
|
||||
public EssentialsRoomEmergencyBase Emergency { get; set; }
|
||||
|
||||
public Privacy.MicrophonePrivacyController MicrophonePrivacy { get; set; }
|
||||
|
||||
public string LogoUrl { get; set; }
|
||||
|
||||
protected SecondsCountdownTimer RoomVacancyShutdownTimer { get; private set; }
|
||||
|
||||
public eVacancyMode VacancyMode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// When volume control devices change, should we zero the one that we are leaving?
|
||||
/// </summary>
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
|
||||
|
||||
#region IHasCurrentSourceInfoChange Members
|
||||
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The SourceListItem last run - containing names and icons
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get { return _currentSourceInfo; }
|
||||
set
|
||||
{
|
||||
if (value == _currentSourceInfo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
|
||||
if (handler != null)
|
||||
{
|
||||
handler(_currentSourceInfo, ChangeType.WillChange);
|
||||
}
|
||||
|
||||
var oldSource = _currentSourceInfo as IInUseTracking;
|
||||
var newSource = value as IInUseTracking;
|
||||
|
||||
UpdateInUseTracking(oldSource, newSource);
|
||||
|
||||
_currentSourceInfo = value;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(_currentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
|
||||
/// <summary>
|
||||
/// Fires when the RoomOccupancy object is set
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> RoomOccupancyIsSet;
|
||||
|
||||
private void SetupRoomVacancyShutdown()
|
||||
{
|
||||
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
|
||||
|
||||
RoomVacancyShutdownTimer.HasFinished += RoomVacancyShutdownPromptTimer_HasFinished; // Shutdown is triggered
|
||||
|
||||
RoomVacancyShutdownPromptSeconds = 1500; // 25 min to prompt warning
|
||||
RoomVacancyShutdownSeconds = 240; // 4 min after prompt will trigger shutdown prompt
|
||||
VacancyMode = eVacancyMode.None;
|
||||
}
|
||||
|
||||
private void SetupShutdownPrompt()
|
||||
{
|
||||
// Setup the ShutdownPromptTimer
|
||||
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
|
||||
ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!ShutdownPromptTimer.IsRunningFeedback.BoolValue)
|
||||
{
|
||||
ShutdownType = eShutdownType.None;
|
||||
}
|
||||
};
|
||||
ShutdownPromptTimer.HasFinished += (o, a) => Shutdown(); // Shutdown is triggered
|
||||
|
||||
ShutdownPromptSeconds = 60;
|
||||
ShutdownVacancySeconds = 120;
|
||||
|
||||
ShutdownType = eShutdownType.None;
|
||||
}
|
||||
|
||||
protected void InitializeDisplay(DisplayBase display)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
display.PowerIsOnFeedback.OutputChange += PowerIsOnFeedbackOnOutputChange;
|
||||
|
||||
display.IsWarmingUpFeedback.OutputChange += IsWarmingUpFeedbackOnOutputChange;
|
||||
display.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedbackOnOutputChange;
|
||||
}
|
||||
|
||||
protected void UpdateInUseTracking(IInUseTracking oldDev, IInUseTracking newDev)
|
||||
{
|
||||
// derigister this room from the device, if it can
|
||||
if (oldDev != null)
|
||||
{
|
||||
oldDev.InUseTracker.RemoveUser(this, "audio");
|
||||
}
|
||||
|
||||
// register this room with new device, if it can
|
||||
if (newDev != null)
|
||||
{
|
||||
newDev.InUseTracker.AddUser(this, "audio");
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs args);
|
||||
protected abstract void IsWarmingUpFeedbackOnOutputChange(object sender, FeedbackEventArgs args);
|
||||
protected abstract void IsCoolingDownFeedbackOnOutputChange(object sender, FeedbackEventArgs args);
|
||||
|
||||
private void RoomVacancyShutdownPromptTimer_HasFinished(object sender, EventArgs e)
|
||||
{
|
||||
switch (VacancyMode)
|
||||
{
|
||||
case eVacancyMode.None:
|
||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||
break;
|
||||
case eVacancyMode.InInitialVacancy:
|
||||
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
|
||||
break;
|
||||
case eVacancyMode.InShutdownWarning:
|
||||
{
|
||||
StartShutdown(eShutdownType.Vacancy);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting Down due to vacancy.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
public void StartShutdown(eShutdownType type)
|
||||
{
|
||||
// Check for shutdowns running. Manual should override other shutdowns
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case eShutdownType.Manual:
|
||||
ShutdownPromptTimer.SecondsToCount = ShutdownPromptSeconds;
|
||||
break;
|
||||
case eShutdownType.Vacancy:
|
||||
ShutdownPromptTimer.SecondsToCount = ShutdownVacancySeconds;
|
||||
break;
|
||||
}
|
||||
ShutdownType = type;
|
||||
ShutdownPromptTimer.Start();
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "ShutdownPromptTimer Started. Type: {0}. Seconds: {1}",
|
||||
ShutdownType, ShutdownPromptTimer.SecondsToCount);
|
||||
}
|
||||
|
||||
public void StartRoomVacancyTimer(eVacancyMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case eVacancyMode.None:
|
||||
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownPromptSeconds;
|
||||
break;
|
||||
case eVacancyMode.InInitialVacancy:
|
||||
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds;
|
||||
break;
|
||||
case eVacancyMode.InShutdownWarning:
|
||||
RoomVacancyShutdownTimer.SecondsToCount = 60;
|
||||
break;
|
||||
}
|
||||
VacancyMode = mode;
|
||||
RoomVacancyShutdownTimer.Start();
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Vacancy Timer Started. Mode: {0}. Seconds: {1}",
|
||||
VacancyMode, RoomVacancyShutdownTimer.SecondsToCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the vacancy mode and shutsdwon the room
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
VacancyMode = eVacancyMode.None;
|
||||
EndShutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is for the derived class to define it's specific shutdown
|
||||
/// requirements but should not be called directly. It is called by Shutdown()
|
||||
/// </summary>
|
||||
protected virtual void EndShutdown()
|
||||
{
|
||||
SetDefaultLevels();
|
||||
|
||||
RunDefaultPresentRoute();
|
||||
|
||||
//CrestronEnvironment.Sleep(1000); //why?
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
|
||||
|
||||
RunRouteAction("roomOff");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Override this to implement a default volume level(s) method
|
||||
/// </summary>
|
||||
public virtual void SetDefaultLevels()
|
||||
{
|
||||
Debug.Console(1, this, "Restoring default levels");
|
||||
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
if (vc != null)
|
||||
{
|
||||
vc.SetVolume(DefaultVolume);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the object to be used as the IOccupancyStatusProvider for the room. Can be an Occupancy Aggregator or a specific device
|
||||
/// </summary>
|
||||
/// <param name="statusProvider"></param>
|
||||
/// <param name="timeoutMinutes"></param>
|
||||
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
|
||||
{
|
||||
var provider = statusProvider as IKeyed;
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Room Occupancy set to device: '{0}'", provider.Key);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Timeout Minutes from Config is: {0}", timeoutMinutes);
|
||||
|
||||
// If status provider is fusion, set flag to remote
|
||||
if (statusProvider is Fusion.EssentialsFusionSystemControllerBase)
|
||||
{
|
||||
OccupancyStatusProviderIsRemote = true;
|
||||
}
|
||||
|
||||
if (timeoutMinutes > 0)
|
||||
{
|
||||
RoomVacancyShutdownSeconds = timeoutMinutes*60;
|
||||
}
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "RoomVacancyShutdownSeconds set to {0}",
|
||||
RoomVacancyShutdownSeconds);
|
||||
|
||||
RoomOccupancy = statusProvider;
|
||||
|
||||
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange -= RoomIsOccupiedFeedback_OutputChange;
|
||||
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
|
||||
|
||||
OnRoomOccupancyIsSet();
|
||||
}
|
||||
|
||||
private void OnRoomOccupancyIsSet()
|
||||
{
|
||||
var handler = RoomOccupancyIsSet;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To allow base class to power room on to last source
|
||||
/// </summary>
|
||||
public virtual void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
RunRouteAction(LastSourceKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To allow base class to power room on to default source
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool RunDefaultPresentRoute()
|
||||
{
|
||||
if (DefaultSourceItem == null)
|
||||
{
|
||||
Debug.Console(0, this, "Unable to run default present route, DefaultSourceItem is null.");
|
||||
return false;
|
||||
}
|
||||
|
||||
RunRouteAction(DefaultSourceItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Vacancy Detected");
|
||||
// Trigger the timer when the room is vacant
|
||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Occupancy Detected");
|
||||
// Reset the timer when the room is occupied
|
||||
RoomVacancyShutdownTimer.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
public abstract void RoomVacatedForTimeoutPeriod(object o);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sourceKey"></param>
|
||||
public virtual void RunRouteAction(string sourceKey)
|
||||
{
|
||||
RunRouteAction(sourceKey, String.Empty, () => { });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||
/// route or commands
|
||||
/// </summary>
|
||||
public virtual void RunRouteAction(string sourceKey, Action successCallback)
|
||||
{
|
||||
RunRouteAction(sourceKey, String.Empty, successCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sourceKey"></param>
|
||||
/// <param name="sourceListKey"></param>
|
||||
public virtual void RunRouteAction(string sourceKey, string sourceListKey)
|
||||
{
|
||||
RunRouteAction(sourceKey, sourceListKey, () => { });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sourceKey"></param>
|
||||
/// <param name="sourceListKey"></param>
|
||||
/// <param name="successCallback"></param>
|
||||
public virtual void RunRouteAction(string sourceKey, string sourceListKey, Action successCallback)
|
||||
{
|
||||
var routeObject =
|
||||
new {RouteKey = sourceKey, SourceListKey = sourceListKey, SuccessCallback = successCallback};
|
||||
CrestronInvoke.BeginInvoke(RunRouteAction, routeObject); // end of BeginInvoke
|
||||
}
|
||||
|
||||
protected virtual void RunRouteAction(object routeObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
RoutingLock.Enter();
|
||||
|
||||
var routeObj = new {RouteKey = "", SourceListKey = "", SuccessCallback = new Action(() => { })};
|
||||
|
||||
routeObj = Cast(routeObj, routeObject);
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeObj.RouteKey);
|
||||
var sourceList = GetSourceListForKey(routeObj.RouteKey, routeObj.SourceListKey);
|
||||
|
||||
if (sourceList == null)
|
||||
{
|
||||
Debug.Console(0, this, "No source list found for key {0}", routeObj.SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = sourceList[routeObj.RouteKey];
|
||||
|
||||
// End usage timer on last source
|
||||
StopUsageTrackingOnCurrentSource(sourceList);
|
||||
|
||||
// Let's run it
|
||||
if (routeObj.RouteKey.ToLower() != "roomoff")
|
||||
{
|
||||
LastSourceKey = routeObj.RouteKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSourceInfoKey = null;
|
||||
}
|
||||
|
||||
foreach (var route in item.RouteList)
|
||||
{
|
||||
var tempVideo = new SourceRouteListItem
|
||||
{
|
||||
DestinationKey = "$defaultDisplay",
|
||||
SourceKey = route.SourceKey,
|
||||
Type = eRoutingSignalType.Video
|
||||
};
|
||||
|
||||
var routeItem = route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase)
|
||||
? tempVideo
|
||||
: route;
|
||||
|
||||
DoRoute(routeItem);
|
||||
}
|
||||
|
||||
// Start usage timer on routed source
|
||||
if (item.SourceDevice is IUsageTracking)
|
||||
{
|
||||
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||
}
|
||||
|
||||
// Set volume control, using default if non provided
|
||||
SetVolumeControl(item);
|
||||
|
||||
// store the name and UI info for routes
|
||||
CurrentSourceInfoKey = routeObj.RouteKey;
|
||||
if (item.SourceKey == "$off")
|
||||
{
|
||||
CurrentSourceInfo = null;
|
||||
}
|
||||
else if (item.SourceKey != null)
|
||||
{
|
||||
CurrentSourceInfo = item;
|
||||
}
|
||||
|
||||
OnFeedback.FireUpdate();
|
||||
|
||||
// report back when done
|
||||
if (routeObj.SuccessCallback != null)
|
||||
{
|
||||
routeObj.SuccessCallback();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
RoutingLock.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
private static T Cast<T>(T typeHolder, object m)
|
||||
{
|
||||
return (T) m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
protected void DoRoute(SourceRouteListItem route)
|
||||
{
|
||||
var dest = GetDestination(route);
|
||||
|
||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IPower)
|
||||
{
|
||||
(dest as IPower).PowerOff();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||
if (source == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey,
|
||||
route.DestinationKey);
|
||||
return;
|
||||
}
|
||||
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||
}
|
||||
}
|
||||
|
||||
private IRoutingSink GetDestination(SourceRouteListItem route)
|
||||
{
|
||||
IRoutingSink dest;
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest = DefaultAudioDevice;
|
||||
}
|
||||
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest = DefaultDisplay;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
|
||||
}
|
||||
|
||||
if (dest != null)
|
||||
{
|
||||
return dest;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||
return dest;
|
||||
}
|
||||
|
||||
protected void SetVolumeControl(SourceListItem item)
|
||||
{
|
||||
IBasicVolumeControls volDev = null;
|
||||
// Handle special cases for volume control
|
||||
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
volDev = DefaultVolumeControls;
|
||||
}
|
||||
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||
}
|
||||
else
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||
if (dev is IBasicVolumeControls)
|
||||
{
|
||||
volDev = dev as IBasicVolumeControls;
|
||||
}
|
||||
else if (dev is IHasVolumeDevice)
|
||||
{
|
||||
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||
}
|
||||
}
|
||||
|
||||
if (volDev == CurrentVolumeControls)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IBasicVolumeWithFeedback vd;
|
||||
// zero the volume on the device we are leaving.
|
||||
// Set the volume to default on device we are entering
|
||||
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||
{
|
||||
vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
SavedVolumeLevels[vd] = (uint) vd.VolumeLevelFeedback.IntValue;
|
||||
vd.SetVolume(0);
|
||||
}
|
||||
CurrentVolumeControls = volDev;
|
||||
if (!ZeroVolumeWhenSwtichingVolumeDevices || !(CurrentVolumeControls is IBasicVolumeWithFeedback))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
var vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort) SavedVolumeLevels[vd] : DefaultVolume);
|
||||
vd.SetVolume(vol);
|
||||
}
|
||||
|
||||
private void StopUsageTrackingOnCurrentSource(Dictionary<string, SourceListItem> sourceList)
|
||||
{
|
||||
if (string.IsNullOrEmpty(LastSourceKey))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var lastSource = sourceList[LastSourceKey].SourceDevice;
|
||||
|
||||
try
|
||||
{
|
||||
if (lastSource is IUsageTracking)
|
||||
{
|
||||
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Dictionary<string, SourceListItem> GetSourceListForKey(string routeKey, string sourceListKey)
|
||||
{
|
||||
var slKey = String.IsNullOrEmpty(sourceListKey) ? SourceListKey : sourceListKey;
|
||||
|
||||
var sourceList = ConfigReader.ConfigObject.GetSourceListForKey(slKey);
|
||||
|
||||
if (sourceList == null)
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", slKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Try to get the list item by it's string key
|
||||
if (sourceList.ContainsKey(routeKey))
|
||||
{
|
||||
return sourceList;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "WARNING: No source list '{0}' found in config source lists '{1}'",
|
||||
routeKey, SourceListKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||
/// </summary>
|
||||
public static void AllRoomsOff()
|
||||
{
|
||||
var allRooms = DeviceManager.AllDevices.OfType<EssentialsRoomBase>().Where(d =>
|
||||
!d.ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
{
|
||||
room.RunRouteAction("roomOff");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To describe the various ways a room may be shutting down
|
||||
/// </summary>
|
||||
public enum eShutdownType
|
||||
{
|
||||
None = 0,
|
||||
External,
|
||||
Manual,
|
||||
Vacancy
|
||||
}
|
||||
|
||||
public enum eVacancyMode
|
||||
{
|
||||
None = 0,
|
||||
InInitialVacancy,
|
||||
InShutdownWarning
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum eWarmingCoolingMode
|
||||
{
|
||||
None,
|
||||
Warming,
|
||||
Cooling
|
||||
}
|
||||
|
||||
public abstract class EssentialsRoomEmergencyBase : IKeyed
|
||||
{
|
||||
protected EssentialsRoomEmergencyBase(string key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
|
||||
#region IKeyed Members
|
||||
|
||||
public string Key { get; private set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
namespace PepperDash.Essentials.Core.Rooms
|
||||
{
|
||||
/// <summary>
|
||||
/// For rooms with in call feedback
|
||||
@@ -0,0 +1,243 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
using PepperDash_Essentials_Core.Devices;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class EssentialsDualDisplayRoom : EssentialsHuddleVtc1Room
|
||||
{
|
||||
public const string DefaultDestinationListKey = "default";
|
||||
private const string LeftDestinationKey = "leftDisplay";
|
||||
private const string RightDestinationKey = "rightDisplay";
|
||||
private EVideoBehavior _videoRoutingBehavior;
|
||||
|
||||
public EssentialsDualDisplayRoomPropertiesConfig RoomConfig { get; private set; }
|
||||
|
||||
public EAudioBehavior AudioRoutingBehavior { get; set; }
|
||||
|
||||
public EVideoBehavior VideoRoutingBehavior
|
||||
{
|
||||
get { return _videoRoutingBehavior; }
|
||||
set
|
||||
{
|
||||
_videoRoutingBehavior = value;
|
||||
var handler = VideoRoutingBehaviorChanged;
|
||||
|
||||
if (handler == null) return;
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler VideoRoutingBehaviorChanged;
|
||||
|
||||
private string _destinationListKey;
|
||||
|
||||
public EssentialsDualDisplayRoom(DeviceConfig config) : base(config)
|
||||
{
|
||||
RoomConfig = config.Properties.ToObject<EssentialsDualDisplayRoomPropertiesConfig>();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public Dictionary<string, DestinationListItem> DestinationList { get; private set; }
|
||||
|
||||
public BoolFeedback LeftDisplayIsWarmingUpFeedback { get; private set; }
|
||||
public BoolFeedback RightDisplayIsWarmingUpFeedback { get; private set; }
|
||||
public BoolFeedback LeftDisplayIsCoolingDownFeedback { get; private set; }
|
||||
public BoolFeedback RightDisplayIsCoolingDownFeedback { get; private set; }
|
||||
|
||||
public IRoutingSinkWithSwitching LeftDisplay { get; private set; }
|
||||
public IRoutingSinkWithSwitching RightDisplay { get; private set; }
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
_destinationListKey = String.IsNullOrEmpty(RoomConfig.DestinationListKey)
|
||||
? DefaultDestinationListKey
|
||||
: RoomConfig.DestinationListKey;
|
||||
|
||||
AudioRoutingBehavior = RoomConfig.DefaultAudioBehavior;
|
||||
VideoRoutingBehavior = RoomConfig.DefaultVideoBehavior;
|
||||
|
||||
InitializeDestinations();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, this, "Error Initializing Room: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeDestinations()
|
||||
{
|
||||
DestinationList = ConfigReader.ConfigObject.GetDestinationListForKey(_destinationListKey);
|
||||
|
||||
if (DestinationList == null)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "No destination list with key {0} found",
|
||||
_destinationListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
//left destination is defined as the display on the 0 surface, at location 0,0 (h, v)
|
||||
var leftDest = GetDestinationForKey(LeftDestinationKey);
|
||||
|
||||
//not found by key, check by expected location
|
||||
if (leftDest == null)
|
||||
{
|
||||
DestinationList.Values.FirstOrDefault(
|
||||
li => li.SurfaceLocation == 0 && li.HorizontalLocation == 0 && li.VerticalLocation == 0);
|
||||
}
|
||||
|
||||
//right destination is defined as the display on the 0 surface, at location 0,0 (h, v)
|
||||
var rightDest = GetDestinationForKey(RightDestinationKey);
|
||||
|
||||
//not found by key, check by expected location
|
||||
if (rightDest == null)
|
||||
{
|
||||
DestinationList.Values.FirstOrDefault(
|
||||
li => li.SurfaceLocation == 0 && li.HorizontalLocation == 1 && li.VerticalLocation == 0);
|
||||
}
|
||||
|
||||
if (leftDest == null || rightDest == null)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Dual destinations not defined. Please check configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
var leftDisplay = leftDest.SinkDevice as DisplayBase;
|
||||
var rightDisplay = rightDest.SinkDevice as DisplayBase;
|
||||
|
||||
if (leftDisplay == null || rightDisplay == null)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"Display for key {0} && key {1} not found. Please check configurattion");
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "LeftDisplay: {0}\r\nRightDisplay: {1}", leftDest.SinkKey,
|
||||
rightDest.SinkKey);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//need displays as DisplayBase later instead of IRoutingSinkWithSwtich
|
||||
LeftDisplay = leftDisplay;
|
||||
RightDisplay = rightDisplay;
|
||||
|
||||
//TODO: Check this definition for on for dual display rooms
|
||||
OnFeedbackFunc = () => CurrentSourceInfo != null && CurrentSourceInfo.Type == eSourceListItemType.Route;
|
||||
|
||||
IsWarmingFeedbackFunc =
|
||||
() => leftDisplay.IsWarmingUpFeedback.BoolValue || rightDisplay.IsWarmingUpFeedback.BoolValue;
|
||||
|
||||
IsCoolingFeedbackFunc = () => leftDisplay.IsWarmingUpFeedback.BoolValue ||
|
||||
rightDisplay.IsCoolingDownFeedback.BoolValue;
|
||||
|
||||
LeftDisplayIsWarmingUpFeedback = new BoolFeedback(() => leftDisplay.IsWarmingUpFeedback.BoolValue);
|
||||
LeftDisplayIsCoolingDownFeedback = new BoolFeedback(() => leftDisplay.IsCoolingDownFeedback.BoolValue);
|
||||
|
||||
|
||||
RightDisplayIsWarmingUpFeedback = new BoolFeedback(() => rightDisplay.IsWarmingUpFeedback.BoolValue);
|
||||
RightDisplayIsCoolingDownFeedback = new BoolFeedback(() => rightDisplay.IsCoolingDownFeedback.BoolValue);
|
||||
|
||||
InitializeDisplay(leftDisplay);
|
||||
InitializeDisplay(rightDisplay);
|
||||
}
|
||||
|
||||
private DestinationListItem GetDestinationForKey(string key)
|
||||
{
|
||||
DestinationListItem returnValue;
|
||||
|
||||
DestinationList.TryGetValue(key, out returnValue);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
protected override void IsCoolingDownFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
LeftDisplayIsCoolingDownFeedback.FireUpdate();
|
||||
RightDisplayIsCoolingDownFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override void IsWarmingUpFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
LeftDisplayIsWarmingUpFeedback.FireUpdate();
|
||||
RightDisplayIsWarmingUpFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
protected override void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
var ld = LeftDisplay as DisplayBase;
|
||||
var rd = RightDisplay as DisplayBase;
|
||||
|
||||
if (ld == null || rd == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//if room is already on and either display is still on, no need to fire update
|
||||
if (OnFeedback.BoolValue && (ld.PowerIsOnFeedback.BoolValue || rd.PowerIsOnFeedback.BoolValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//if both displays are off, room is off, clear the current source
|
||||
if (!ld.PowerIsOnFeedback.BoolValue && !rd.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
CurrentSourceInfo = null;
|
||||
}
|
||||
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
public void RouteAction(string sourceKey, string destinationKey)
|
||||
{
|
||||
var routeItem = new SourceRouteListItem
|
||||
{
|
||||
DestinationKey = destinationKey,
|
||||
SourceKey = sourceKey,
|
||||
Type = eRoutingSignalType.AudioVideo
|
||||
};
|
||||
|
||||
DoRoute(routeItem);
|
||||
}
|
||||
|
||||
public void SelectSource(string sourceKey, string sourceListKey)
|
||||
{
|
||||
var srcList = GetSourceListForKey(sourceKey, sourceListKey);
|
||||
|
||||
var src = srcList[sourceKey];
|
||||
|
||||
if (src.SourceKey != "roomoff")
|
||||
{
|
||||
LastSourceKey = sourceKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSourceInfoKey = null;
|
||||
}
|
||||
|
||||
SetVolumeControl(src);
|
||||
|
||||
if (src.SourceKey == "$off")
|
||||
{
|
||||
CurrentSourceInfo = null;
|
||||
} else if (src.SourceKey != null)
|
||||
{
|
||||
CurrentSourceInfo = src;
|
||||
}
|
||||
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Rooms;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IRunRouteAction,
|
||||
IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay, IHasCurrentSourceInfoChange
|
||||
{
|
||||
public EssentialsHuddleSpaceRoom(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertiesConfig = config.Properties.ToObject<EssentialsHuddleRoomPropertiesConfig>();
|
||||
DefaultDisplay =
|
||||
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||
//why are we assuming IRoutingSinkWithSwitching here?
|
||||
|
||||
DefaultAudioDevice =
|
||||
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Error building room: \n{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||
{
|
||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||
}
|
||||
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||
{
|
||||
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||
}
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
|
||||
SourceListKey = String.IsNullOrEmpty(PropertiesConfig.SourceListKey)
|
||||
? DefaultSourceListKey
|
||||
: PropertiesConfig.SourceListKey;
|
||||
|
||||
EnablePowerOnToLastSource = true;
|
||||
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsWarmingFeedbackFunc = () => disp.IsWarmingUpFeedback.BoolValue;
|
||||
|
||||
IsCoolingFeedbackFunc = () => disp.IsCoolingDownFeedback.BoolValue;
|
||||
|
||||
OnFeedbackFunc = () => CurrentSourceInfo != null
|
||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route;
|
||||
|
||||
InitializeDisplay(disp);
|
||||
}
|
||||
|
||||
protected override void IsCoolingDownFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
protected override void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
{
|
||||
var display = sender as DisplayBase;
|
||||
|
||||
if (display == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (display.PowerIsOnFeedback.BoolValue == OnFeedback.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!display.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
CurrentSourceInfo = null;
|
||||
}
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
protected override void IsWarmingUpFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
|
||||
if (IsWarmingUpFeedback.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var displayVolumeControl = DefaultDisplay as IBasicVolumeWithFeedback;
|
||||
|
||||
if (displayVolumeControl == null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
|
||||
"Default display {0} is not volume control control provider", DefaultDisplay.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
displayVolumeControl.SetVolume(DefaultVolume);
|
||||
}
|
||||
|
||||
protected override void CustomSetConfig(DeviceConfig config)
|
||||
{
|
||||
var newPropertiesConfig =
|
||||
JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
|
||||
|
||||
if (newPropertiesConfig != null)
|
||||
{
|
||||
PropertiesConfig = newPropertiesConfig;
|
||||
}
|
||||
|
||||
ConfigWriter.UpdateRoomConfig(config);
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
// Add Occupancy object from config
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
{
|
||||
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
}
|
||||
|
||||
LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||
SourceListKey = PropertiesConfig.SourceListKey;
|
||||
DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
DefaultVolume = (ushort) (PropertiesConfig.Volumes.Master.Level*65535/100);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||
{
|
||||
//TODO: Implement RoomVacatedForTimeoutPeriod
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices.AudioCodec;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
using PepperDash.Essentials.Core.Devices.VideoCodec;
|
||||
using PepperDash.Essentials.Core.Rooms;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange,
|
||||
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec,
|
||||
IHasDefaultDisplay, IHasInCallFeedback
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// "codecOsd"
|
||||
/// </summary>
|
||||
public const string DefaultCodecRouteString = "codecOsd";
|
||||
|
||||
public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; protected set; }
|
||||
|
||||
public EssentialsHuddleVtc1Room(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertiesConfig = config.Properties.ToObject<EssentialsHuddleVtc1PropertiesConfig>();
|
||||
DefaultDisplay =
|
||||
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||
|
||||
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
||||
VideoCodecBase;
|
||||
if (VideoCodec == null)
|
||||
{
|
||||
throw new ArgumentNullException("codec cannot be null");
|
||||
}
|
||||
|
||||
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
||||
AudioCodecBase;
|
||||
if (AudioCodec == null)
|
||||
{
|
||||
Debug.Console(0, this, "No Audio Codec Found");
|
||||
}
|
||||
|
||||
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSink;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Error building room: \n{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Temporary implementation. Returns the schedule-ready object or null if none. Fow now,
|
||||
/// always returns the VideoCodec if it is capable
|
||||
/// </summary>
|
||||
public IHasScheduleAwareness ScheduleSource
|
||||
{
|
||||
get { return VideoCodec as IHasScheduleAwareness; }
|
||||
}
|
||||
|
||||
#region IHasAudioCodec Members
|
||||
|
||||
public AudioCodecBase AudioCodec { get; protected set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHasVideoCodec Members
|
||||
|
||||
public BoolFeedback InCallFeedback { get; protected set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||
/// </summary>
|
||||
public IntFeedback CallTypeFeedback { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// When something in the room is sharing with the far end or through other means
|
||||
/// </summary>
|
||||
public BoolFeedback IsSharingFeedback { get; protected set; }
|
||||
|
||||
//************************
|
||||
|
||||
public VideoCodecBase VideoCodec { get; protected set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPrivacy Members
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BoolFeedback PrivacyModeIsOnFeedback { get; protected set; }
|
||||
|
||||
public void PrivacyModeOff()
|
||||
{
|
||||
VideoCodec.PrivacyModeOff();
|
||||
}
|
||||
|
||||
public void PrivacyModeOn()
|
||||
{
|
||||
VideoCodec.PrivacyModeOn();
|
||||
}
|
||||
|
||||
public void PrivacyModeToggle()
|
||||
{
|
||||
VideoCodec.PrivacyModeToggle();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRunDefaultCallRoute Members
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the room when started into call mode without presenting a source
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool RunDefaultCallRoute()
|
||||
{
|
||||
RunRouteAction(DefaultCodecRouteString);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DefaultAudioDevice != null)
|
||||
{
|
||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||
}
|
||||
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||
{
|
||||
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||
}
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
|
||||
|
||||
// Combines call feedback from both codecs if available
|
||||
InCallFeedback = new BoolFeedback(() =>
|
||||
{
|
||||
var inAudioCall = AudioCodec != null && AudioCodec.IsInCall;
|
||||
var inVideoCall = VideoCodec != null && VideoCodec.IsInCall;
|
||||
|
||||
return inAudioCall || inVideoCall;
|
||||
});
|
||||
|
||||
// Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback
|
||||
MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
|
||||
|
||||
// Get emergency object, if any
|
||||
Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Emergency Config evaluated.");
|
||||
|
||||
|
||||
VideoCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
|
||||
|
||||
if (AudioCodec != null)
|
||||
{
|
||||
AudioCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => IsSharingFeedback.FireUpdate();
|
||||
|
||||
// link privacy to VC (for now?)
|
||||
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => PrivacyModeIsOnFeedback.FireUpdate();
|
||||
|
||||
CallTypeFeedback = new IntFeedback(() => 0);
|
||||
|
||||
SourceListKey = String.IsNullOrEmpty(PropertiesConfig.SourceListKey)
|
||||
? DefaultSourceListKey
|
||||
: PropertiesConfig.SourceListKey;
|
||||
EnablePowerOnToLastSource = true;
|
||||
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnFeedbackFunc = () => CurrentSourceInfo != null
|
||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route;
|
||||
|
||||
IsWarmingFeedbackFunc = () => disp.IsWarmingUpFeedback.BoolValue;
|
||||
IsCoolingFeedbackFunc = () => disp.IsCoolingDownFeedback.BoolValue;
|
||||
|
||||
InitializeDisplay(disp);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, this, "Error Initializing Room: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CustomSetConfig(DeviceConfig config)
|
||||
{
|
||||
var newPropertiesConfig =
|
||||
JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>(config.Properties.ToString());
|
||||
|
||||
if (newPropertiesConfig != null)
|
||||
{
|
||||
PropertiesConfig = newPropertiesConfig;
|
||||
}
|
||||
|
||||
ConfigWriter.UpdateRoomConfig(config);
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
// Add Occupancy object from config
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
|
||||
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
}
|
||||
|
||||
LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||
SourceListKey = PropertiesConfig.SourceListKey;
|
||||
DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
DefaultVolume = (ushort) (PropertiesConfig.Volumes.Master.Level*65535/100);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void EndShutdown()
|
||||
{
|
||||
VideoCodec.EndAllCalls();
|
||||
|
||||
if (AudioCodec != null)
|
||||
{
|
||||
AudioCodec.EndAllCalls();
|
||||
}
|
||||
|
||||
base.EndShutdown();
|
||||
}
|
||||
|
||||
|
||||
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||
{
|
||||
//Implement this
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsRoomBase
|
||||
|
||||
protected override void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
var disp = sender as DisplayBase;
|
||||
|
||||
if (disp == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
CurrentSourceInfo = null;
|
||||
}
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (disp.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void IsCoolingDownFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
protected override void IsWarmingUpFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
|
||||
if (IsWarmingUpFeedback.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var basicVolumeWithFeedback = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
if (basicVolumeWithFeedback != null)
|
||||
{
|
||||
basicVolumeWithFeedback.SetVolume(DefaultVolume);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Rooms;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for rooms with more than a single display
|
||||
/// </summary>
|
||||
public abstract class EssentialsNDisplayRoomBase : EssentialsRoomBase, IHasMultipleDisplays
|
||||
{
|
||||
//public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||
|
||||
public Dictionary<eSourceListItemDestinationTypes, IRoutingSinkWithSwitching> Displays { get; protected set;}
|
||||
|
||||
protected EssentialsNDisplayRoomBase(DeviceConfig config)
|
||||
: base (config)
|
||||
{
|
||||
Displays = new Dictionary<eSourceListItemDestinationTypes, IRoutingSinkWithSwitching>();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
}
|
||||
|
||||
public class RoutingOutputPort : RoutingPort
|
||||
public class RoutingOutputPort : RoutingPort, IInUseTracking
|
||||
{
|
||||
/// <summary>
|
||||
/// The IRoutingOutputs object this port lives on
|
||||
|
||||
@@ -66,8 +66,7 @@ namespace PepperDash.Essentials.Core
|
||||
StringIncrement = stringIncrement;
|
||||
|
||||
// Count the enable lines to see what max items is
|
||||
MaxDefinedItems = (ushort)SRL.BooleanInput
|
||||
.Where(s => s.Name.Contains("Enable")).Count();
|
||||
MaxDefinedItems = (ushort)SRL.BooleanInput.Count(s => s.Name.Contains("Enable"));
|
||||
Debug.Console(2, "SRL {0} contains max {1} items", SRL.ID, MaxDefinedItems);
|
||||
|
||||
SRL.SigChange -= new SmartObjectSigChangeEventHandler(SRL_SigChange);
|
||||
|
||||
@@ -7,7 +7,8 @@ using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Core.Devices.AudioCodec;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
|
||||
{
|
||||
public class CodecActiveCallItem
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
|
||||
{
|
||||
public enum eCodecCallDirection
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
public enum eCodecCallStatus
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
|
||||
{
|
||||
public enum eCodecCallType
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
public enum eMeetingPrivacy
|
||||
{
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Devices.Core.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Requirements for a device that has dialing capabilities
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
|
||||
@@ -99,19 +99,11 @@
|
||||
<Reference Include="System.Data" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AudioCodec\AudioCodecBase.cs" />
|
||||
<Compile Include="AudioCodec\Interfaces\IAudioCodecInfo.cs" />
|
||||
<Compile Include="AudioCodec\Interfaces\IHasAudioCodec.cs" />
|
||||
<Compile Include="AudioCodec\MockAC\MockAC.cs" />
|
||||
<Compile Include="AudioCodec\MockAC\MockAcPropertiesConfig.cs" />
|
||||
<Compile Include="Cameras\CameraBase.cs" />
|
||||
<Compile Include="Cameras\CameraVisca.cs" />
|
||||
<Compile Include="Cameras\IHasCameraPresets.cs" />
|
||||
<Compile Include="Codec\eCodecCallDirection.cs" />
|
||||
<Compile Include="Codec\eCodecCallType.cs" />
|
||||
<Compile Include="Codec\eCodecCallStatus.cs" />
|
||||
<Compile Include="Codec\eMeetingPrivacy.cs" />
|
||||
<Compile Include="Codec\iCodecAudio.cs" />
|
||||
<Compile Include="ImageProcessors\TVOneCorio.cs" />
|
||||
<Compile Include="ImageProcessors\TVOneCorioPropertiesConfig.cs" />
|
||||
<Compile Include="Power Controllers\Digitallogger.cs" />
|
||||
@@ -123,13 +115,6 @@
|
||||
<Compile Include="VideoCodec\CiscoCodec\RoomPresets.cs" />
|
||||
<Compile Include="Cameras\CameraControl.cs" />
|
||||
<Compile Include="Display\PanasonicThDisplay.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\iVideoCodecInfo.cs" />
|
||||
<Compile Include="Codec\iHasCallFavorites.cs" />
|
||||
<Compile Include="Codec\iHasCallHistory.cs" />
|
||||
<Compile Include="Codec\iHasContentSharing.cs" />
|
||||
<Compile Include="Codec\iHasDialer.cs" />
|
||||
<Compile Include="Codec\iHasDirectory.cs" />
|
||||
<Compile Include="Codec\iHasScheduleAwareness.cs" />
|
||||
<Compile Include="Display\ComTcpDisplayBase.cs" />
|
||||
<Compile Include="Display\AvocorVTFDisplay.cs" />
|
||||
<Compile Include="Display\InputInterfaces.cs" />
|
||||
@@ -160,7 +145,6 @@
|
||||
<Compile Include="VideoCodec\CiscoCodec\CiscoSparkCodec.cs" />
|
||||
<Compile Include="VideoCodec\CiscoCodec\CiscoSparkCodecPropertiesConfig.cs" />
|
||||
<Compile Include="VideoCodec\CiscoCodec\xStatusSparkPlus.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasVideoCodec.cs" />
|
||||
<Compile Include="VideoCodec\MockVC\MockCodecDirectory.cs" />
|
||||
<Compile Include="VideoCodec\MockVC\MockVCCamera.cs" />
|
||||
<Compile Include="VideoCodec\MockVC\MockVcPropertiesConfig.cs" />
|
||||
@@ -168,12 +152,8 @@
|
||||
<Compile Include="VideoCodec\CiscoCodec\xConfiguration.cs" />
|
||||
<Compile Include="VideoCodec\CiscoCodec\xEvent.cs" />
|
||||
<Compile Include="VideoCodec\CiscoCodec\HttpApiServer.cs" />
|
||||
<Compile Include="Codec\CodecActiveCallItem.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasCodecLayouts.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasCodecSelfview.cs" />
|
||||
<Compile Include="VideoCodec\MockVC\MockVC.cs" />
|
||||
<Compile Include="VideoCodec\CiscoCodec\xStatus.cs" />
|
||||
<Compile Include="VideoCodec\VideoCodecBase.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ResponseObjects.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoom.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomCamera.cs" />
|
||||
|
||||
@@ -6,6 +6,7 @@ using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Rooms;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
@@ -352,7 +352,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
foreach (Call c in b.DialInfo.Calls.Call)
|
||||
{
|
||||
meeting.Calls.Add(new PepperDash.Essentials.Devices.Common.Codec.Call()
|
||||
meeting.Calls.Add(new Essentials.Core.Devices.Codec.Call()
|
||||
{
|
||||
Number = c.Number.Value,
|
||||
Protocol = c.Protocol.Value,
|
||||
|
||||
@@ -10,11 +10,11 @@ using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices.VideoCodec;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
using PepperDash.Essentials.Devices.Core.VideoCodec;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
{
|
||||
@@ -283,7 +283,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
{
|
||||
|
||||
|
||||
var props = JsonConvert.DeserializeObject<Codec.CiscoSparkCodecPropertiesConfig>(config.Properties.ToString());
|
||||
var props = JsonConvert.DeserializeObject<Essentials.Core.Devices.Codec.CiscoSparkCodecPropertiesConfig>(config.Properties.ToString());
|
||||
|
||||
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
|
||||
PeopleCountFeedback = new IntFeedback(PeopleCountFeedbackFunc);
|
||||
@@ -395,6 +395,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
TieLineCollection.Default.Add(tl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a list of call history entries returned by a Cisco codec to the generic list type
|
||||
/// </summary>
|
||||
/// <param name="entries"></param>
|
||||
/// <returns></returns>
|
||||
public List<CodecCallHistory.CallHistoryEntry> ConvertCiscoCallHistoryToGeneric(List<CiscoCallHistory.Entry> entries)
|
||||
{
|
||||
var genericEntries = entries.Select(entry => new CodecCallHistory.CallHistoryEntry
|
||||
{
|
||||
Name = entry.DisplayName.Value,
|
||||
Number = entry.CallbackNumber.Value,
|
||||
StartTime = entry.LastOccurrenceStartTime.Value,
|
||||
OccurrenceHistoryId = entry.LastOccurrenceHistoryId.Value,
|
||||
OccurrenceType = ConvertToOccurenceTypeEnum(entry.OccurrenceType.Value)
|
||||
}).ToList();
|
||||
|
||||
// Check if list is empty and if so, add an item to display No Recent Calls
|
||||
if (genericEntries.Count == 0)
|
||||
genericEntries.Add(CallHistory.ListEmptyEntry);
|
||||
|
||||
return genericEntries;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the HTTP feedback server and syncronizes state of codec
|
||||
/// </summary>
|
||||
@@ -436,6 +459,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes the Cisco occurence type and converts it to the matching enum
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public eCodecOccurrenceType ConvertToOccurenceTypeEnum(string s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case "Placed":
|
||||
{
|
||||
return eCodecOccurrenceType.Placed;
|
||||
}
|
||||
case "Received":
|
||||
{
|
||||
return eCodecOccurrenceType.Received;
|
||||
}
|
||||
case "NoAnswer":
|
||||
{
|
||||
return eCodecOccurrenceType.NoAnswer;
|
||||
}
|
||||
default:
|
||||
return eCodecOccurrenceType.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires when initial codec sync is completed. Used to then send commands to get call history, phonebook, bookings, etc.
|
||||
/// </summary>
|
||||
@@ -601,8 +649,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
//JsonSerializerSettings settings = new JsonSerializerSettings();
|
||||
//settings.NullValueHandling = NullValueHandling.Ignore;
|
||||
//settings.MissingMemberHandling = MissingMemberHandling.Ignore;
|
||||
//settings.ObjectCreationHandling = ObjectCreationHandling.Auto;
|
||||
|
||||
//settings.ObjectCreationHandling = ObjectCreationHandling.Auto;
|
||||
|
||||
if (response.IndexOf("\"Status\":{") > -1 || response.IndexOf("\"Status\": {") > -1)
|
||||
{
|
||||
// Status Message
|
||||
@@ -775,7 +823,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
if (!SyncState.InitialConfigurationMessageWasReceived)
|
||||
SendText("xConfiguration");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (response.IndexOf("\"Configuration\":{") > -1 || response.IndexOf("\"Configuration\": {") > -1)
|
||||
{
|
||||
// Configuration Message
|
||||
@@ -791,9 +839,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (response.IndexOf("\"Event\":{") > -1 || response.IndexOf("\"Event\": {") > -1)
|
||||
{
|
||||
{
|
||||
if (response.IndexOf("\"CallDisconnect\":{") > -1 || response.IndexOf("\"CallDisconnect\": {") > -1)
|
||||
{
|
||||
CiscoCodecEvents.RootObject eventReceived = new CiscoCodecEvents.RootObject();
|
||||
@@ -801,28 +849,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
JsonConvert.PopulateObject(response, eventReceived);
|
||||
|
||||
EvalutateDisconnectEvent(eventReceived);
|
||||
}
|
||||
}
|
||||
else if (response.IndexOf("\"Bookings\":{") > -1 || response.IndexOf("\"Bookings\": {") > -1) // The list has changed, reload it
|
||||
{
|
||||
GetBookings(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (response.IndexOf("\"CommandResponse\":{") > -1 || response.IndexOf("\"CommandResponse\": {") > -1)
|
||||
{
|
||||
// CommandResponse Message
|
||||
|
||||
// CommandResponse Message
|
||||
|
||||
if (response.IndexOf("\"CallHistoryRecentsResult\":{") > -1 || response.IndexOf("\"CallHistoryRecentsResult\": {") > -1)
|
||||
{
|
||||
var codecCallHistory = new CiscoCallHistory.RootObject();
|
||||
|
||||
JsonConvert.PopulateObject(response, codecCallHistory);
|
||||
|
||||
CallHistory.ConvertCiscoCallHistoryToGeneric(codecCallHistory.CommandResponse.CallHistoryRecentsResult.Entry);
|
||||
}
|
||||
var tempRecentCallsList =
|
||||
ConvertCiscoCallHistoryToGeneric(
|
||||
codecCallHistory.CommandResponse.CallHistoryRecentsResult.Entry);
|
||||
CallHistory.UpdateCallHistory(tempRecentCallsList);
|
||||
}
|
||||
else if (response.IndexOf("\"CallHistoryDeleteEntryResult\":{") > -1 || response.IndexOf("\"CallHistoryDeleteEntryResult\": {") > -1)
|
||||
{
|
||||
GetCallHistory();
|
||||
}
|
||||
}
|
||||
else if (response.IndexOf("\"PhonebookSearchResult\":{") > -1 || response.IndexOf("\"PhonebookSearchResult\": {") > -1)
|
||||
{
|
||||
var codecPhonebookResponse = new CiscoCodecPhonebook.RootObject();
|
||||
@@ -1678,26 +1729,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string SipUri
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CodecStatus.Status.SIP != null && CodecStatus.Status.SIP.AlternateURI.Primary.URI.Value != null)
|
||||
{
|
||||
return CodecStatus.Status.SIP.AlternateURI.Primary.URI.Value;
|
||||
}
|
||||
else if (CodecStatus.Status.UserInterface != null &&
|
||||
CodecStatus.Status.UserInterface.ContactInfo.ContactMethod[0].Number.Value != null)
|
||||
{
|
||||
return CodecStatus.Status.UserInterface.ContactInfo.ContactMethod[0].Number.Value;
|
||||
}
|
||||
else
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override string SipUri
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CodecStatus.Status.SIP != null && CodecStatus.Status.SIP.AlternateURI.Primary.URI.Value != null)
|
||||
{
|
||||
return CodecStatus.Status.SIP.AlternateURI.Primary.URI.Value;
|
||||
}
|
||||
else if (CodecStatus.Status.UserInterface != null &&
|
||||
CodecStatus.Status.UserInterface.ContactInfo.ContactMethod[0].Number.Value != null)
|
||||
{
|
||||
return CodecStatus.Status.UserInterface.ContactInfo.ContactMethod[0].Number.Value;
|
||||
}
|
||||
else
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool AutoAnswerEnabled
|
||||
{
|
||||
get
|
||||
@@ -1850,6 +1901,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
else
|
||||
InitialSyncComplete = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class CiscoSparkCodecFactory : EssentialsDeviceFactory<CiscoSparkCodec>
|
||||
|
||||
@@ -7,7 +7,7 @@ using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
public class CiscoSparkCodecPropertiesConfig
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
@@ -240,7 +240,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
foreach (ContactMethod m in c.ContactMethod)
|
||||
{
|
||||
|
||||
var tempContactMethod = new PepperDash.Essentials.Devices.Common.Codec.ContactMethod();
|
||||
var tempContactMethod = new Essentials.Core.Devices.Codec.ContactMethod();
|
||||
|
||||
eContactMethodCallType callType = eContactMethodCallType.Unknown;
|
||||
if (!string.IsNullOrEmpty(m.CallType.Value))
|
||||
@@ -299,11 +299,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
/// <returns></returns>
|
||||
public static CodecDirectory ConvertCiscoPhonebookToGeneric(PhonebookSearchResult result)
|
||||
{
|
||||
var directory = new Codec.CodecDirectory();
|
||||
var directory = new Essentials.Core.Devices.Codec.CodecDirectory();
|
||||
|
||||
var folders = new List<Codec.DirectoryItem>();
|
||||
var folders = new List<Essentials.Core.Devices.Codec.DirectoryItem>();
|
||||
|
||||
var contacts = new List<Codec.DirectoryItem>();
|
||||
var contacts = new List<Essentials.Core.Devices.Codec.DirectoryItem>();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -370,7 +370,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
device = eContactMethodDevice.Other;
|
||||
}
|
||||
|
||||
contact.ContactMethods.Add(new PepperDash.Essentials.Devices.Common.Codec.ContactMethod()
|
||||
contact.ContactMethods.Add(new Essentials.Core.Devices.Codec.ContactMethod()
|
||||
{
|
||||
Number = m.Number.Value,
|
||||
ContactMethodId = m.ContactMethodId.Value,
|
||||
|
||||
@@ -6,7 +6,7 @@ using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user