mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-29 04:15:00 +00:00
Compare commits
75 Commits
1.6.8-alph
...
1.6.10-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b62849d9d | ||
|
|
d311b6fef9 | ||
|
|
4a642b1e36 | ||
|
|
de4f003c67 | ||
|
|
708ee1a8ff | ||
|
|
7196d0aba8 | ||
|
|
522c107ce6 | ||
|
|
cb29775004 | ||
|
|
fccbb55344 | ||
|
|
b2402402d9 | ||
|
|
f0a3b27e3b | ||
|
|
57ebd2b608 | ||
|
|
695ff5487f | ||
|
|
66cd39c013 | ||
|
|
91eec8c258 | ||
|
|
d2c308c009 | ||
|
|
a4a99f4a9b | ||
|
|
eb114b4a95 | ||
|
|
93e8d50e55 | ||
|
|
3c6fc978d4 | ||
|
|
01ddf1721c | ||
|
|
1ee87c0499 | ||
|
|
f8ae6264f7 | ||
|
|
3e56859943 | ||
|
|
945db8a233 | ||
|
|
6e4fa48b9d | ||
|
|
7e8f216afb | ||
|
|
b09c151738 | ||
|
|
56cf54a644 | ||
|
|
169e897748 | ||
|
|
748b1ca147 | ||
|
|
2e636082bb | ||
|
|
9204ad2701 | ||
|
|
8feb7a142c | ||
|
|
d990930b19 | ||
|
|
4d67279827 | ||
|
|
a78b29b0a1 | ||
|
|
2c36c0f2cb | ||
|
|
2eaf21b1e0 | ||
|
|
099e387570 | ||
|
|
c4755f23cd | ||
|
|
9c4650b4af | ||
|
|
43d7fab04d | ||
|
|
d2b7e71c4a | ||
|
|
ab6d44e604 | ||
|
|
0dc2e9d134 | ||
|
|
3a024b8d4c | ||
|
|
05e2422cb4 | ||
|
|
fc5d4f946d | ||
|
|
45c1e25e4f | ||
|
|
f11bdcfd53 | ||
|
|
9888fbf047 | ||
|
|
9171610e34 | ||
|
|
7a8c1f3165 | ||
|
|
008a052045 | ||
|
|
93a5f2e3b2 | ||
|
|
0e4edca08a | ||
|
|
f9925f9ec9 | ||
|
|
f283f82bbc | ||
|
|
ab5dd5f756 | ||
|
|
e22c71853f | ||
|
|
8bf27ecbd9 | ||
|
|
d94d003050 | ||
|
|
25c4d94366 | ||
|
|
91dda3213e | ||
|
|
b41dd23c7f | ||
|
|
14ad0eee48 | ||
|
|
56e106ff32 | ||
|
|
b67424c1e1 | ||
|
|
c366ee9d12 | ||
|
|
5ec97f2e31 | ||
|
|
98c20464d7 | ||
|
|
b1aa9c3306 | ||
|
|
db6ab3ee98 | ||
|
|
ce86255119 |
@@ -70,6 +70,14 @@ namespace PepperDash.Essentials.Bridges
|
||||
/// Range reports the highest supported HDCP state level for the corresponding input card
|
||||
/// </summary>
|
||||
public uint HdcpSupportCapability { get; set; }
|
||||
/// <summary>
|
||||
/// DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback
|
||||
/// </summary>
|
||||
public uint InputStreamCardStatus { get; set; }
|
||||
/// <summary>
|
||||
/// DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback
|
||||
/// </summary>
|
||||
public uint OutputStreamCardStatus { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Serials
|
||||
@@ -115,6 +123,8 @@ namespace PepperDash.Essentials.Bridges
|
||||
InputUsb = 700; //701-899
|
||||
HdcpSupportState = 1000; //1001-1199
|
||||
HdcpSupportCapability = 1200; //1201-1399
|
||||
InputStreamCardStatus = 1500; //1501-1532
|
||||
OutputStreamCardStatus = 1600; //1601-1632
|
||||
|
||||
|
||||
//Serial
|
||||
@@ -145,6 +155,8 @@ namespace PepperDash.Essentials.Bridges
|
||||
OutputEndpointOnline = OutputEndpointOnline + joinOffset;
|
||||
HdcpSupportState = HdcpSupportState + joinOffset;
|
||||
HdcpSupportCapability = HdcpSupportCapability + joinOffset;
|
||||
InputStreamCardStatus = InputStreamCardStatus + joinOffset;
|
||||
OutputStreamCardStatus = OutputStreamCardStatus + joinOffset;
|
||||
OutputDisabledByHdcp = OutputDisabledByHdcp + joinOffset;
|
||||
TxAdvancedIsPresent = TxAdvancedIsPresent + joinOffset;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,10 @@ using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
using PepperDash.Essentials.Devices.Common;
|
||||
using PepperDash.Essentials.DM;
|
||||
using PepperDash.Essentials.Fusion;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
@@ -52,7 +53,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (Debug.DoNotLoadOnNextBoot)
|
||||
{
|
||||
CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronInvoke.BeginInvoke((o) => GoWithLoad()), "go", "Loads configuration file",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
@@ -431,12 +432,26 @@ namespace PepperDash.Essentials
|
||||
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
|
||||
if (room != null)
|
||||
{
|
||||
// default IPID
|
||||
uint fusionIpId = 0xf1;
|
||||
|
||||
// default to no join map key
|
||||
string fusionJoinMapKey = string.Empty;
|
||||
|
||||
var fusionConfig = room.Config.Properties["fusion"].ToObject<EssentialsRoomFusionConfig>();
|
||||
|
||||
if (fusionConfig != null)
|
||||
{
|
||||
fusionIpId = fusionConfig.IpIdInt;
|
||||
fusionJoinMapKey = fusionConfig.JoinMapKey;
|
||||
}
|
||||
|
||||
if (room is EssentialsHuddleSpaceRoom)
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
|
||||
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
@@ -448,12 +463,24 @@ namespace PepperDash.Essentials
|
||||
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));
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
else if (room is EssentialsTechRoom)
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion");
|
||||
@@ -536,23 +563,31 @@ namespace PepperDash.Essentials
|
||||
string logoLight = null;
|
||||
string logo = null;
|
||||
|
||||
if (c.Properties["logoDark"] != null)
|
||||
try
|
||||
{
|
||||
logoDark = c.Properties["logoDark"].Value<string>("type");
|
||||
}
|
||||
if (c.Properties["logoDark"] != null)
|
||||
{
|
||||
logoDark = c.Properties["logoDark"].Value<string>("type");
|
||||
}
|
||||
|
||||
if (c.Properties["logoLight"] != null)
|
||||
if (c.Properties["logoLight"] != null)
|
||||
{
|
||||
logoLight = c.Properties["logoLight"].Value<string>("type");
|
||||
}
|
||||
|
||||
if (c.Properties["logo"] != null)
|
||||
{
|
||||
logo = c.Properties["logo"].Value<string>("type");
|
||||
}
|
||||
|
||||
return ((logoDark != null && logoDark == "system") ||
|
||||
(logoLight != null && logoLight == "system") || (logo != null && logo == "system"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logoLight = c.Properties["logoLight"].Value<string>("type");
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Unable to find logo information in any room config");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c.Properties["logo"] != null)
|
||||
{
|
||||
logo = c.Properties["logo"].Value<string>("type");
|
||||
}
|
||||
|
||||
return ((logoDark != null && logoDark == "system") ||
|
||||
(logoLight != null && logoLight == "system") || (logo != null && logo == "system"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,574 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.CrestronThread;
|
||||
using Crestron.SimplSharpPro.Diagnostics;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Rooms.Config;
|
||||
using PepperDash.Essentials.DM;
|
||||
using PepperDash.Essentials.Fusion;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using EssentialsRoomConfigHelper = PepperDash.Essentials.Core.Rooms.Config.EssentialsRoomConfigHelper;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class ControlSystem : CrestronControlSystem
|
||||
{
|
||||
HttpLogoServer LogoServer;
|
||||
|
||||
private CTimer _startTimer;
|
||||
private const long StartupTime = 500;
|
||||
|
||||
public ControlSystem()
|
||||
: base()
|
||||
{
|
||||
Thread.MaxNumberOfUserThreads = 400;
|
||||
Global.ControlSystem = this;
|
||||
DeviceManager.Initialize(this);
|
||||
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entry point for the program
|
||||
/// </summary>
|
||||
public override void InitializeSystem()
|
||||
{
|
||||
_startTimer = new CTimer(StartSystem,StartupTime);
|
||||
}
|
||||
|
||||
private void StartSystem(object obj)
|
||||
{
|
||||
DeterminePlatform();
|
||||
|
||||
if (Debug.DoNotLoadOnNextBoot)
|
||||
{
|
||||
CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "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(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 =>
|
||||
{
|
||||
foreach (var tl in TieLineCollection.Default)
|
||||
CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
|
||||
},
|
||||
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse
|
||||
("Current running configuration. This is the merged system and template configuration");
|
||||
CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject
|
||||
(ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented));
|
||||
}, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
|
||||
"System URL: {0}\r" +
|
||||
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
|
||||
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(DeviceManager.GetRoutingPorts,
|
||||
"getroutingports", "Reports all routing ports, if any. Requires a device key", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
if (!Debug.DoNotLoadOnNextBoot)
|
||||
{
|
||||
GoWithLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the program is running on a processor (appliance) or server (VC-4).
|
||||
///
|
||||
/// Sets Global.FilePathPrefix and Global.ApplicationDirectoryPathPrefix based on platform
|
||||
/// </summary>
|
||||
public void DeterminePlatform()
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Determining Platform....");
|
||||
|
||||
string filePathPrefix;
|
||||
|
||||
var dirSeparator = Global.DirectorySeparator;
|
||||
|
||||
string directoryPrefix;
|
||||
|
||||
directoryPrefix = Crestron.SimplSharp.CrestronIO.Directory.GetApplicationRootDirectory();
|
||||
|
||||
var fullVersion = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false);
|
||||
|
||||
AssemblyInformationalVersionAttribute fullVersionAtt = fullVersion[0] as AssemblyInformationalVersionAttribute;
|
||||
|
||||
Global.SetAssemblyVersion(fullVersionAtt.InformationalVersion);
|
||||
|
||||
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", Global.AssemblyVersion);
|
||||
|
||||
// Check if User/ProgramX exists
|
||||
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User"
|
||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
|
||||
{
|
||||
Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber);
|
||||
filePathPrefix = directoryPrefix + dirSeparator + "User"
|
||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
||||
}
|
||||
// Check if Nvram/Programx exists
|
||||
else if (Directory.Exists(directoryPrefix + dirSeparator + "Nvram"
|
||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
|
||||
{
|
||||
Debug.Console(0, @"Nvram/program{0} directory found", InitialParametersClass.ApplicationNumber);
|
||||
filePathPrefix = directoryPrefix + dirSeparator + "Nvram"
|
||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
||||
}
|
||||
// If neither exists, set path to User/ProgramX
|
||||
else
|
||||
{
|
||||
Debug.Console(0, @"No previous directory found. Using User/program{0}", InitialParametersClass.ApplicationNumber);
|
||||
filePathPrefix = directoryPrefix + dirSeparator + "User"
|
||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
||||
}
|
||||
}
|
||||
else // Handles Linux OS (Virtual Control)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on Virtual Control Server", Global.AssemblyVersion);
|
||||
|
||||
// Set path to User/
|
||||
filePathPrefix = directoryPrefix + dirSeparator + "User" + dirSeparator;
|
||||
}
|
||||
|
||||
Global.SetFilePathPrefix(filePathPrefix);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Unable to Determine Platform due to Exception: {0}", e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begins the process of loading resources including plugins and configuration data
|
||||
/// </summary>
|
||||
public void GoWithLoad()
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.SetDoNotLoadOnNextBoot(false);
|
||||
|
||||
PluginLoader.AddProgramAssemblies();
|
||||
|
||||
new Core.DeviceFactory();
|
||||
new Devices.Common.DeviceFactory();
|
||||
new DM.DeviceFactory();
|
||||
new DeviceFactory();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration");
|
||||
|
||||
var filesReady = SetupFilesystem();
|
||||
if (filesReady)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Checking for plugins");
|
||||
PluginLoader.LoadPlugins();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Folder structure verified. Loading config...");
|
||||
if (!ConfigReader.LoadConfig2())
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Essentials Load complete with errors");
|
||||
return;
|
||||
}
|
||||
|
||||
Load();
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Essentials load complete\r\n" +
|
||||
"-------------------------------------------------------------");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0,
|
||||
@"----------------------------------------------
|
||||
------------------------------------------------
|
||||
------------------------------------------------
|
||||
Essentials file structure setup completed.
|
||||
Please load config, sgd and ir files and
|
||||
restart program.
|
||||
------------------------------------------------
|
||||
------------------------------------------------
|
||||
------------------------------------------------");
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r\n{0}", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Notify the OS that the program intitialization has completed
|
||||
SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Verifies filesystem is set up. IR, SGD, and programX folders
|
||||
/// </summary>
|
||||
bool SetupFilesystem()
|
||||
{
|
||||
Debug.Console(0, "Verifying and/or creating folder structure");
|
||||
var configDir = Global.FilePathPrefix;
|
||||
var configExists = Directory.Exists(configDir);
|
||||
if (!configExists)
|
||||
Directory.Create(configDir);
|
||||
|
||||
var irDir = Global.FilePathPrefix + "ir";
|
||||
if (!Directory.Exists(irDir))
|
||||
Directory.Create(irDir);
|
||||
|
||||
var sgdDir = Global.FilePathPrefix + "sgd";
|
||||
if (!Directory.Exists(sgdDir))
|
||||
Directory.Create(sgdDir);
|
||||
|
||||
var pluginDir = Global.FilePathPrefix + "plugins";
|
||||
if (!Directory.Exists(pluginDir))
|
||||
Directory.Create(pluginDir);
|
||||
|
||||
return configExists;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void TearDown()
|
||||
{
|
||||
Debug.Console(0, "Tearing down existing system");
|
||||
DeviceManager.DeactivateAll();
|
||||
|
||||
TieLineCollection.Default.Clear();
|
||||
|
||||
foreach (var key in DeviceManager.GetDevices())
|
||||
DeviceManager.RemoveDevice(key);
|
||||
|
||||
Debug.Console(0, "Tear down COMPLETE");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void Load()
|
||||
{
|
||||
LoadDevices();
|
||||
LoadTieLines();
|
||||
LoadRooms();
|
||||
LoadLogoServer();
|
||||
|
||||
DeviceManager.ActivateAll();
|
||||
|
||||
var mobileControl = GetMobileControlDevice();
|
||||
|
||||
if (mobileControl == null) return;
|
||||
|
||||
mobileControl.LinkSystemMonitorToAppServer();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads all devices from config and adds them to DeviceManager
|
||||
/// </summary>
|
||||
public void LoadDevices()
|
||||
{
|
||||
|
||||
// Build the processor wrapper class
|
||||
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));
|
||||
|
||||
// Add global System Monitor device
|
||||
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
||||
{
|
||||
DeviceManager.AddDevice(
|
||||
new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor"));
|
||||
}
|
||||
|
||||
foreach (var devConf in ConfigReader.ConfigObject.Devices)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Creating device '{0}', type '{1}'", devConf.Key, devConf.Type);
|
||||
// Skip this to prevent unnecessary warnings
|
||||
if (devConf.Key == "processor")
|
||||
{
|
||||
if (devConf.Type.ToLower() != Global.ControlSystem.ControllerPrompt.ToLower())
|
||||
Debug.Console(0,
|
||||
"WARNING: Config file defines processor type as '{0}' but actual processor is '{1}'! Some ports may not be available",
|
||||
devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper());
|
||||
|
||||
// Check if the processor is a DMPS model
|
||||
if (this.ControllerPrompt.IndexOf("dmps", StringComparison.OrdinalIgnoreCase) > -1)
|
||||
{
|
||||
Debug.Console(2, "Adding DmpsRoutingController for {0} to Device Manager.", this.ControllerPrompt);
|
||||
|
||||
var propertiesConfig = JsonConvert.DeserializeObject<DM.Config.DmpsRoutingPropertiesConfig>(devConf.Properties.ToString());
|
||||
|
||||
if(propertiesConfig == null)
|
||||
propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig();
|
||||
|
||||
var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig);
|
||||
|
||||
DeviceManager.AddDevice(dmpsRoutingController);
|
||||
}
|
||||
else if (this.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);
|
||||
DeviceManager.AddDevice(tpController);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Unable to deserialize buttons collection for device: {0}", devConf.Key);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "************Processor is not DMPS type***************");
|
||||
}
|
||||
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try local factories first
|
||||
IKeyed newDev = null;
|
||||
|
||||
if (newDev == null)
|
||||
newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf);
|
||||
|
||||
if (newDev != null)
|
||||
DeviceManager.AddDevice(newDev);
|
||||
else
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
|
||||
}
|
||||
}
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to load tie lines. This should run after devices have loaded
|
||||
/// </summary>
|
||||
public void LoadTieLines()
|
||||
{
|
||||
// In the future, we can't necessarily just clear here because devices
|
||||
// might be making their own internal sources/tie lines
|
||||
|
||||
var tlc = TieLineCollection.Default;
|
||||
//tlc.Clear();
|
||||
if (ConfigReader.ConfigObject.TieLines == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var tieLineConfig in ConfigReader.ConfigObject.TieLines)
|
||||
{
|
||||
var newTL = tieLineConfig.GetTieLine();
|
||||
if (newTL != null)
|
||||
tlc.Add(newTL);
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Tie Lines Loaded.");
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads all rooms from config and adds them to DeviceManager
|
||||
/// </summary>
|
||||
public void LoadRooms()
|
||||
{
|
||||
if (ConfigReader.ConfigObject.Rooms == null)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Configuration contains no rooms - Is this intentional? This may be a valid configuration.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
|
||||
{
|
||||
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
|
||||
if (room == null)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key);'
|
||||
return;
|
||||
}
|
||||
|
||||
var huddleRoom = room as EssentialsHuddleSpaceRoom;
|
||||
var vtcRoom = room as EssentialsHuddleVtc1Room;
|
||||
|
||||
if (huddleRoom != null)
|
||||
{
|
||||
DeviceManager.AddDevice(huddleRoom);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
else if (room is EssentialsHuddleVtc1Room)
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
// Mobile Control bridge
|
||||
var bridge = new MobileControlEssentialsHuddleSpaceRoomBridge(huddleRoom);
|
||||
AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
|
||||
DeviceManager.AddDevice(bridge);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion");
|
||||
DeviceManager.AddDevice(room);
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController(vtcRoom, 0xf1));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
// Mobile Control bridge
|
||||
var bridge = new MobileControlEssentialsHuddleSpaceRoomBridge(room);
|
||||
AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
|
||||
DeviceManager.AddDevice(bridge);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Cannot create room from config, key '{0}' - Is this intentional? This may be a valid configuration.", roomConfig.Key);
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded.");
|
||||
|
||||
}
|
||||
|
||||
private static void CreateMobileControlBridge(EssentialsRoomBase room)
|
||||
{
|
||||
var mobileControl = GetMobileControlDevice();
|
||||
|
||||
if (mobileControl == null) return;
|
||||
|
||||
mobileControl.CreateMobileControlRoomBridge(room, mobileControl);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added...");
|
||||
}
|
||||
|
||||
private static IMobileControl GetMobileControlDevice()
|
||||
{
|
||||
var mobileControlList = DeviceManager.AllDevices.OfType<IMobileControl>().ToList();
|
||||
|
||||
if (mobileControlList.Count > 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Warning,
|
||||
"Multiple instances of Mobile Control Server found.");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mobileControlList.Count > 0)
|
||||
{
|
||||
return mobileControlList[0];
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control not enabled for this system");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires up a logo server if not already running
|
||||
/// </summary>
|
||||
void LoadLogoServer()
|
||||
{
|
||||
if (ConfigReader.ConfigObject.Rooms == null)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "No rooms configured. Bypassing Logo server startup.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!ConfigReader.ConfigObject.Rooms.Any(
|
||||
CheckRoomConfig))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "No rooms configured to use system Logo server. Bypassing Logo server startup");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
LogoServer = new HttpLogoServer(8080, Global.DirectorySeparator + "html" + Global.DirectorySeparator + "logo");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "NOTICE: Logo server cannot be started. Likely already running in another program");
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckRoomConfig(DeviceConfig c)
|
||||
{
|
||||
string logoDark = null;
|
||||
string logoLight = null;
|
||||
string logo = null;
|
||||
|
||||
if (c.Properties["logoDark"] != null)
|
||||
{
|
||||
logoDark = c.Properties["logoDark"].Value<string>("type");
|
||||
}
|
||||
|
||||
if (c.Properties["logoLight"] != null)
|
||||
{
|
||||
logoLight = c.Properties["logoLight"].Value<string>("type");
|
||||
}
|
||||
|
||||
if (c.Properties["logo"] != null)
|
||||
{
|
||||
logo = c.Properties["logo"].Value<string>("type");
|
||||
}
|
||||
|
||||
return ((logoDark != null && logoDark == "system") ||
|
||||
(logoLight != null && logoLight == "system") || (logo != null && logo == "system"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ using PepperDash.Essentials.Core.Routing;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class Amplifier : EssentialsDevice, IRoutingSink
|
||||
public class Amplifier : EssentialsDevice, IRoutingSinkNoSwitching
|
||||
{
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
|
||||
@@ -1,429 +1,358 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.Fusion;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
|
||||
namespace PepperDash.Essentials.Fusion
|
||||
{
|
||||
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
|
||||
{
|
||||
private BooleanSigData _codecIsInCall;
|
||||
|
||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
|
||||
: base(room, ipId)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called in base class constructor before RVI and GUID files are built
|
||||
/// </summary>
|
||||
protected override void ExecuteCustomSteps()
|
||||
{
|
||||
SetUpCodec();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a static asset for the codec and maps the joins to the main room symbol
|
||||
/// </summary>
|
||||
private void SetUpCodec()
|
||||
{
|
||||
try
|
||||
{
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (essentialsHuddleVtc1Room == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var codec = essentialsHuddleVtc1Room.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
|
||||
bool codecHasIpInfo = false;
|
||||
var codecComm = codec.Communication;
|
||||
|
||||
string codecIpAddress = string.Empty;
|
||||
int 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)
|
||||
{
|
||||
StringSigData codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC",
|
||||
eSigIoMask.InputSigOnly);
|
||||
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
|
||||
|
||||
StringSigData 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, Core.Devices.Codec.CodecCallStatusItemChangeEventArgs e)
|
||||
{
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (essentialsHuddleVtc1Room == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var codec = essentialsHuddleVtc1Room.VideoCodec;
|
||||
|
||||
_codecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
||||
}
|
||||
|
||||
// These methods are overridden because they access the room class which is of a different type
|
||||
|
||||
protected override void CreateSymbolAndBasicSigs(uint ipId)
|
||||
{
|
||||
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
||||
|
||||
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
|
||||
|
||||
FusionRoom.Register();
|
||||
|
||||
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
|
||||
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange +=
|
||||
FusionRoomSchedule_DeviceExtenderSigChange;
|
||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange +=
|
||||
ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
|
||||
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule",
|
||||
"Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod",
|
||||
"Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting",
|
||||
"Creates and Ad Hoc meeting for on hour or until the next meeting",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
// Room to fusion room
|
||||
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
|
||||
|
||||
// Moved to
|
||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source",
|
||||
eSigIoMask.InputSigOnly);
|
||||
// Don't think we need to get current status of this as nothing should be alive yet.
|
||||
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (essentialsHuddleVtc1Room != null)
|
||||
{
|
||||
essentialsHuddleVtc1Room.CurrentSourceChange += Room_CurrentSourceInfoChange;
|
||||
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(
|
||||
essentialsHuddleVtc1Room.PowerOnToDefaultOrLastSource);
|
||||
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(
|
||||
() => essentialsHuddleVtc1Room.RunRouteAction("roomOff", Room.SourceListKey));
|
||||
}
|
||||
|
||||
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
||||
}
|
||||
|
||||
protected override void SetUpSources()
|
||||
{
|
||||
// Sources
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
|
||||
if (essentialsHuddleVtc1Room == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey(essentialsHuddleVtc1Room.SourceListKey);
|
||||
if (dict != null)
|
||||
{
|
||||
// NEW PROCESS:
|
||||
// Make these lists and insert the fusion attributes by iterating these
|
||||
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
|
||||
uint i = 1;
|
||||
foreach (var kvp in setTopBoxes)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 5) // We only have five spots
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
|
||||
i = 1;
|
||||
foreach (var kvp in discPlayers)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 5) // We only have five spots
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop);
|
||||
i = 1;
|
||||
foreach (var kvp in laptops)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 10) // We only have ten spots???
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var 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}'",
|
||||
essentialsHuddleVtc1Room.SourceListKey, Room.Key);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SetUpDisplay()
|
||||
{
|
||||
try
|
||||
{
|
||||
//Setup Display Usage Monitoring
|
||||
|
||||
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
|
||||
|
||||
// Consider updating this in multiple display systems
|
||||
|
||||
foreach (var display in displays.Cast<DisplayBase>())
|
||||
{
|
||||
display.UsageTracker = new UsageTracking(display) {UsageIsTracked = true};
|
||||
display.UsageTracker.DeviceUsageEnded +=
|
||||
UsageTracker_DeviceUsageEnded;
|
||||
}
|
||||
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (essentialsHuddleVtc1Room == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var defaultDisplay = essentialsHuddleVtc1Room.DefaultDisplay as TwoWayDisplayBase;
|
||||
if (defaultDisplay == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
|
||||
return;
|
||||
}
|
||||
|
||||
var dispPowerOnAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
defaultDisplay.PowerOn();
|
||||
}
|
||||
});
|
||||
var dispPowerOffAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
defaultDisplay.PowerOff();
|
||||
}
|
||||
});
|
||||
|
||||
// Display to fusion room sigs
|
||||
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
if (defaultDisplay is IDisplayUsage)
|
||||
{
|
||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
}
|
||||
|
||||
|
||||
MapDisplayToRoomJoins(1, 158, defaultDisplay);
|
||||
|
||||
|
||||
var deviceConfig =
|
||||
ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
|
||||
|
||||
//Check for existing asset in GUIDs collection
|
||||
|
||||
FusionAsset tempAsset;
|
||||
|
||||
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||
{
|
||||
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new asset
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
|
||||
defaultDisplay.Name, "Display", "");
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
|
||||
tempAsset.InstanceId);
|
||||
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
|
||||
// Use extension methods
|
||||
dispAsset.TrySetMakeModel(defaultDisplay);
|
||||
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, TwoWayDisplayBase display)
|
||||
{
|
||||
var displayName = string.Format("Display {0} - ", displayIndex);
|
||||
|
||||
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (essentialsHuddleVtc1Room == null || display != essentialsHuddleVtc1Room.DefaultDisplay)
|
||||
{
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.Fusion;
|
||||
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
|
||||
namespace PepperDash.Essentials.Fusion
|
||||
{
|
||||
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
|
||||
{
|
||||
BooleanSigData CodecIsInCall;
|
||||
|
||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
|
||||
: base(room, ipId, joinMapKey)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called in base class constructor before RVI and GUID files are built
|
||||
/// </summary>
|
||||
protected override void ExecuteCustomSteps()
|
||||
{
|
||||
SetUpCodec();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a static asset for the codec and maps the joins to the main room symbol
|
||||
/// </summary>
|
||||
void SetUpCodec()
|
||||
{
|
||||
try
|
||||
{
|
||||
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
||||
|
||||
if (codec == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
|
||||
return;
|
||||
}
|
||||
|
||||
codec.UsageTracker = new UsageTracking(codec);
|
||||
codec.UsageTracker.UsageIsTracked = true;
|
||||
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||
|
||||
var codecPowerOnAction = new Action<bool>(b => { if (!b) codec.StandbyDeactivate(); });
|
||||
var codecPowerOffAction = new Action<bool>(b => { if (!b) codec.StandbyActivate(); });
|
||||
|
||||
// Map FusionRoom Attributes:
|
||||
|
||||
// Codec volume
|
||||
var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.Metadata.Description, 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(JoinMap.VcCodecInCall.JoinNumber, JoinMap.VcCodecInCall.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
codec.CallStatusChange += new EventHandler<PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
|
||||
|
||||
// Online status
|
||||
if (codec is ICommunicationMonitor)
|
||||
{
|
||||
var c = codec as ICommunicationMonitor;
|
||||
var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, JoinMap.VcCodecOnline.Metadata.Description, 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, JoinMap.VcCodecOnline.Metadata.Description);
|
||||
}
|
||||
|
||||
// Codec IP Address
|
||||
bool codecHasIpInfo = false;
|
||||
var codecComm = codec.Communication;
|
||||
|
||||
string codecIpAddress = string.Empty;
|
||||
int codecIpPort = 0;
|
||||
|
||||
StringSigData codecIpAddressSig;
|
||||
StringSigData codecIpPortSig;
|
||||
|
||||
if(codecComm is GenericSshClient)
|
||||
{
|
||||
codecIpAddress = (codecComm as GenericSshClient).Hostname;
|
||||
codecIpPort = (codecComm as GenericSshClient).Port;
|
||||
codecHasIpInfo = true;
|
||||
}
|
||||
else if (codecComm is GenericTcpIpClient)
|
||||
{
|
||||
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
|
||||
codecIpPort = (codecComm as GenericTcpIpClient).Port;
|
||||
codecHasIpInfo = true;
|
||||
}
|
||||
|
||||
if (codecHasIpInfo)
|
||||
{
|
||||
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, JoinMap.VcCodecIpAddress.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
|
||||
|
||||
codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, JoinMap.VcCodecIpPort.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
|
||||
}
|
||||
|
||||
var tempAsset = new FusionAsset();
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
|
||||
|
||||
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||
{
|
||||
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new asset
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", "");
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Codec", tempAsset.InstanceId);
|
||||
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
|
||||
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
|
||||
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
|
||||
|
||||
// TODO: Map relevant attributes on asset symbol
|
||||
|
||||
codecAsset.TrySetMakeModel(codec);
|
||||
codecAsset.TryLinkAssetErrorToCommunication(codec);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
|
||||
{
|
||||
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
||||
|
||||
CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
||||
}
|
||||
|
||||
// These methods are overridden because they access the room class which is of a different type
|
||||
|
||||
protected override void CreateSymbolAndBasicSigs(uint ipId)
|
||||
{
|
||||
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
||||
|
||||
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
|
||||
|
||||
FusionRoom.Register();
|
||||
|
||||
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
|
||||
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange;
|
||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
|
||||
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
// Room to fusion room
|
||||
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
|
||||
|
||||
// Moved to
|
||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.Metadata.Description, 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));
|
||||
|
||||
|
||||
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
||||
}
|
||||
|
||||
protected override void SetUpSources()
|
||||
{
|
||||
// Sources
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey);
|
||||
if (dict != null)
|
||||
{
|
||||
// NEW PROCESS:
|
||||
// Make these lists and insert the fusion attributes by iterating these
|
||||
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
|
||||
uint i = 1;
|
||||
foreach (var kvp in setTopBoxes)
|
||||
{
|
||||
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.Metadata.Description + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
|
||||
break;
|
||||
}
|
||||
|
||||
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
|
||||
i = 1;
|
||||
foreach (var kvp in discPlayers)
|
||||
{
|
||||
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.Metadata.Description + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + 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);
|
||||
i = 1;
|
||||
foreach (var kvp in laptops)
|
||||
{
|
||||
TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.Metadata.Description + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var kvp in dict)
|
||||
{
|
||||
var usageDevice = kvp.Value.SourceDevice as IUsageTracking;
|
||||
|
||||
if (usageDevice != null)
|
||||
{
|
||||
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device);
|
||||
usageDevice.UsageTracker.UsageIsTracked = true;
|
||||
usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
|
||||
(Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SetUpDisplay()
|
||||
{
|
||||
try
|
||||
{
|
||||
//Setup Display Usage Monitoring
|
||||
|
||||
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
|
||||
|
||||
// Consider updating this in multiple display systems
|
||||
|
||||
foreach (DisplayBase display in displays)
|
||||
{
|
||||
display.UsageTracker = new UsageTracking(display);
|
||||
display.UsageTracker.UsageIsTracked = true;
|
||||
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
||||
}
|
||||
|
||||
var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
|
||||
if (defaultDisplay == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
|
||||
return;
|
||||
}
|
||||
|
||||
var dispPowerOnAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOn(); });
|
||||
var dispPowerOffAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOff(); });
|
||||
|
||||
// Display to fusion room sigs
|
||||
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
|
||||
var defaultDisplayTwoWay = defaultDisplay as IHasPowerControlWithFeedback;
|
||||
if (defaultDisplayTwoWay != null)
|
||||
{
|
||||
defaultDisplayTwoWay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
}
|
||||
|
||||
if (defaultDisplay is IDisplayUsage)
|
||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
|
||||
MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay);
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
|
||||
|
||||
//Check for existing asset in GUIDs collection
|
||||
|
||||
var tempAsset = new FusionAsset();
|
||||
|
||||
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||
{
|
||||
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new asset
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", "");
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
||||
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
|
||||
|
||||
var defaultTwoWayDisplay = defaultDisplay as IHasPowerControlWithFeedback;
|
||||
if (defaultTwoWayDisplay != null)
|
||||
{
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
if (defaultDisplay is IDisplayUsage)
|
||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
}
|
||||
|
||||
// Use extension methods
|
||||
dispAsset.TrySetMakeModel(defaultDisplay);
|
||||
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display)
|
||||
{
|
||||
string displayName = string.Format("Display {0} - ", displayIndex);
|
||||
|
||||
|
||||
if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay)
|
||||
{
|
||||
// Power on
|
||||
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
|
||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
|
||||
|
||||
// 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(); }); ;
|
||||
|
||||
var displayTwoWay = display as IHasPowerControlWithFeedback;
|
||||
if (displayTwoWay != null)
|
||||
{
|
||||
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
displayTwoWay.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); }); ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,10 +129,25 @@
|
||||
<Compile Include="Bridges\JoinMaps\SetTopBoxControllerJoinMap.cs" />
|
||||
<Compile Include="Bridges\JoinMaps\StatusSignControllerJoinMap.cs" />
|
||||
<Compile Include="Bridges\JoinMaps\SystemMonitorJoinMap.cs" />
|
||||
<Compile Include="ControlSystem.cs" />
|
||||
<Compile Include="Factory\DeviceFactory.cs" />
|
||||
<Compile Include="Devices\Amplifier.cs" />
|
||||
<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\Config\EssentialsTechRoomConfig.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="Room\Types\EssentialsTechRoom.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />
|
||||
@@ -162,6 +177,7 @@
|
||||
<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" />
|
||||
@@ -202,9 +218,6 @@
|
||||
<Name>PepperDash_Essentials_DM</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="UIDrivers\EssentialsDualDisplay\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
|
||||
@@ -22,30 +22,25 @@ namespace PepperDash.Essentials.Room.Config
|
||||
public static Device GetRoomObject(DeviceConfig roomConfig)
|
||||
{
|
||||
var typeName = roomConfig.Type.ToLower();
|
||||
|
||||
if (typeName == "huddle")
|
||||
{
|
||||
var huddle = new EssentialsHuddleSpaceRoom(roomConfig);
|
||||
|
||||
return huddle;
|
||||
return new EssentialsHuddleSpaceRoom(roomConfig);
|
||||
}
|
||||
else if (typeName == "huddlevtc1")
|
||||
{
|
||||
var rm = new EssentialsHuddleVtc1Room(roomConfig);
|
||||
|
||||
return rm;
|
||||
}
|
||||
else if (typeName == "ddvc01Bridge")
|
||||
{
|
||||
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
|
||||
}
|
||||
else if (typeName == "dualdisplay")
|
||||
{
|
||||
var rm = new EssentialsDualDisplayRoom(roomConfig);
|
||||
if (typeName == "huddlevtc1")
|
||||
{
|
||||
return new EssentialsHuddleVtc1Room(roomConfig);
|
||||
}
|
||||
if (typeName == "ddvc01bridge")
|
||||
{
|
||||
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
|
||||
}
|
||||
if (typeName == "dualdisplay")
|
||||
{
|
||||
return new EssentialsDualDisplayRoom(roomConfig);
|
||||
}
|
||||
|
||||
return rm;
|
||||
}
|
||||
|
||||
return null;
|
||||
return typeName != "techroom" ? null : new EssentialsTechRoom(roomConfig);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -182,6 +177,9 @@ namespace PepperDash.Essentials.Room.Config
|
||||
[JsonProperty("volumes")]
|
||||
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
||||
|
||||
[JsonProperty("fusion")]
|
||||
public EssentialsRoomFusionConfig Fusion { get; set; }
|
||||
|
||||
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
||||
|
||||
@@ -225,6 +223,32 @@ namespace PepperDash.Essentials.Room.Config
|
||||
|
||||
}
|
||||
|
||||
public class EssentialsRoomFusionConfig
|
||||
{
|
||||
public uint IpIdInt
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Convert.ToUInt32(IpId, 16);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new FormatException(string.Format("ERROR:Unable to convert IP ID: {0} to hex. Error:\n{1}", IpId));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("ipId")]
|
||||
public string IpId { get; set; }
|
||||
|
||||
[JsonProperty("joinMapKey")]
|
||||
public string JoinMapKey { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class EssentialsRoomMicrophonePrivacyConfig
|
||||
{
|
||||
[JsonProperty("deviceKey")]
|
||||
|
||||
40
PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs
Normal file
40
PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
public class EssentialsTechRoomConfig
|
||||
{
|
||||
[JsonProperty("dummySourceKey")]
|
||||
public string DummySourceKey { get; set; }
|
||||
|
||||
[JsonProperty("displays")]
|
||||
public List<string> Displays;
|
||||
|
||||
[JsonProperty("tuners")]
|
||||
public List<string> Tuners;
|
||||
|
||||
[JsonProperty("userPin")]
|
||||
public string UserPin;
|
||||
|
||||
[JsonProperty("techPin")]
|
||||
public string TechPin;
|
||||
|
||||
[JsonProperty("presetsFileName")]
|
||||
public string PresetsFileName;
|
||||
|
||||
[JsonProperty("scheduledEvents")]
|
||||
public List<ScheduledEventConfig> ScheduledEvents;
|
||||
|
||||
[JsonProperty("isPrimary")] public bool IsPrimary;
|
||||
|
||||
[JsonProperty("isTvPresetsProvider")] public bool IsTvPresetsProvider;
|
||||
|
||||
public EssentialsTechRoomConfig()
|
||||
{
|
||||
Displays = new List<string>();
|
||||
Tuners = new List<string>();
|
||||
ScheduledEvents = new List<ScheduledEventConfig>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
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;
|
||||
@@ -74,8 +77,9 @@ namespace PepperDash.Essentials
|
||||
var leftDisp = LeftDisplay as DisplayBase;
|
||||
var rightDisp = RightDisplay as DisplayBase;
|
||||
if (leftDisp != null && RightDisplay != null)
|
||||
return rightDisp != null && (leftDisp.IsWarmingUpFeedback.BoolValue || rightDisp.IsWarmingUpFeedback.BoolValue);
|
||||
return false;
|
||||
return leftDisp.IsWarmingUpFeedback.BoolValue || rightDisp.IsWarmingUpFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -92,8 +96,9 @@ namespace PepperDash.Essentials
|
||||
var leftDisp = LeftDisplay as DisplayBase;
|
||||
var rightDisp = RightDisplay as DisplayBase;
|
||||
if (leftDisp != null && RightDisplay != null)
|
||||
return rightDisp != null && (leftDisp.IsCoolingDownFeedback.BoolValue || rightDisp.IsCoolingDownFeedback.BoolValue);
|
||||
return false;
|
||||
return leftDisp.IsCoolingDownFeedback.BoolValue || rightDisp.IsCoolingDownFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -115,7 +120,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"
|
||||
@@ -123,27 +128,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"
|
||||
@@ -156,7 +161,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||
|
||||
readonly CCriticalSection _sourceSelectLock = new CCriticalSection();
|
||||
CCriticalSection SourceSelectLock = new CCriticalSection();
|
||||
|
||||
public EssentialsDualDisplayRoom(DeviceConfig config)
|
||||
: base(config)
|
||||
@@ -191,12 +196,12 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
|
||||
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
||||
VideoCodecBase;
|
||||
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
|
||||
if (VideoCodec == null)
|
||||
throw new ArgumentNullException("codec cannot be null");
|
||||
|
||||
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
||||
AudioCodecBase;
|
||||
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
|
||||
if (AudioCodec == null)
|
||||
Debug.Console(0, this, "No Audio Codec Found");
|
||||
|
||||
@@ -212,8 +217,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
if (DefaultAudioDevice != null)
|
||||
DefaultVolumeControls = DefaultAudioDevice;
|
||||
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
@@ -228,12 +233,12 @@ namespace PepperDash.Essentials
|
||||
InitializeDisplay(rightDisp);
|
||||
|
||||
// Get Microphone Privacy object, if any
|
||||
MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
|
||||
|
||||
// Get emergency object, if any
|
||||
Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Emergency Config evaluated.");
|
||||
|
||||
@@ -249,20 +254,23 @@ namespace PepperDash.Essentials
|
||||
if (VideoCodec != null)
|
||||
inVideoCall = VideoCodec.IsInCall;
|
||||
|
||||
return inAudioCall || inVideoCall;
|
||||
if (inAudioCall || inVideoCall)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
VideoCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
|
||||
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
|
||||
if (AudioCodec != null)
|
||||
AudioCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
|
||||
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
|
||||
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => IsSharingFeedback.FireUpdate();
|
||||
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
|
||||
|
||||
// link privacy to VC (for now?)
|
||||
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => PrivacyModeIsOnFeedback.FireUpdate();
|
||||
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||
|
||||
CallTypeFeedback = new IntFeedback(() => 0);
|
||||
|
||||
@@ -296,18 +304,13 @@ namespace PepperDash.Essentials
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
if (IsWarmingUpFeedback.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var basicVolumeWithFeedback = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
if (basicVolumeWithFeedback != null)
|
||||
{
|
||||
basicVolumeWithFeedback.SetVolume(DefaultVolume);
|
||||
}
|
||||
if (!IsWarmingUpFeedback.BoolValue)
|
||||
(CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||
};
|
||||
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
};
|
||||
disp.IsCoolingDownFeedback.OutputChange += (o, a) => IsCoolingDownFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +328,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
// Add Occupancy object from config
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
|
||||
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||
@@ -378,7 +381,6 @@ namespace PepperDash.Essentials
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="sourceListKey"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||
{
|
||||
RunRouteAction(routeKey, sourceListKey, null);
|
||||
@@ -388,17 +390,14 @@ namespace PepperDash.Essentials
|
||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||
/// route or commands
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="sourceListKey"></param>
|
||||
/// <param name="successCallback"></param>
|
||||
/// <param name="name"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
|
||||
{
|
||||
// Run this on a separate thread
|
||||
//new CTimer
|
||||
CrestronInvoke.BeginInvoke(o =>
|
||||
new CTimer(o =>
|
||||
{
|
||||
// try to prevent multiple simultaneous selections
|
||||
_sourceSelectLock.TryEnter();
|
||||
SourceSelectLock.TryEnter();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -420,9 +419,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
|
||||
@@ -442,7 +441,7 @@ namespace PepperDash.Essentials
|
||||
if (routeKey.ToLower() != "roomoff")
|
||||
{
|
||||
|
||||
_lastSourceKey = routeKey;
|
||||
LastSourceKey = routeKey;
|
||||
}
|
||||
//else
|
||||
// CurrentSourceInfoKey = null;
|
||||
@@ -527,7 +526,7 @@ namespace PepperDash.Essentials
|
||||
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||
}
|
||||
|
||||
_sourceSelectLock.Leave();
|
||||
SourceSelectLock.Leave();
|
||||
}, 0); // end of CTimer
|
||||
}
|
||||
|
||||
@@ -536,8 +535,6 @@ 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
|
||||
@@ -561,7 +558,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
private bool DoRoute(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
|
||||
bool DoRoute(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
|
||||
{
|
||||
IRoutingSink dest = null;
|
||||
|
||||
@@ -625,9 +622,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>
|
||||
@@ -635,11 +632,10 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public static void AllRoomsOff()
|
||||
{
|
||||
var allRooms = DeviceManager.AllDevices.OfType<EssentialsHuddleSpaceRoom>().Where(d => !d.ExcludeFromGlobalFunctions);
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
{
|
||||
room.RunRouteAction("roomOff", room.SourceListKey);
|
||||
}
|
||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as EssentialsHuddleSpaceRoom).SourceListKey);
|
||||
}
|
||||
|
||||
#region IPrivacy Members
|
||||
|
||||
@@ -1,5 +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.Config;
|
||||
@@ -7,21 +13,148 @@ using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IRunRouteAction,
|
||||
IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay, IHasCurrentSourceInfoChange
|
||||
{
|
||||
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 EssentialsHuddleSpaceRoom(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertiesConfig = config.Properties.ToObject<EssentialsHuddleRoomPropertiesConfig>();
|
||||
DefaultDisplay =
|
||||
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||
//why are we assuming IRoutingSinkWithSwitching here?
|
||||
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>
|
||||
(config.Properties.ToString());
|
||||
DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||
|
||||
DefaultAudioDevice =
|
||||
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
|
||||
|
||||
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
@@ -31,57 +164,16 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
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)
|
||||
? "default"
|
||||
: 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)
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||
@@ -97,57 +189,70 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
if (!IsWarmingUpFeedback.BoolValue)
|
||||
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||
};
|
||||
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
SourceListKey = "default";
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
RunRouteAction(DefaultSourceItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
// Add Occupancy object from config
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
{
|
||||
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
}
|
||||
|
||||
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||
@@ -158,9 +263,272 @@ namespace PepperDash.Essentials
|
||||
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 IHasPowerControl)
|
||||
(dest as IHasPowerControl).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)
|
||||
{
|
||||
//TODO: Implement RoomVacatedForTimeoutPeriod
|
||||
//Implement this
|
||||
}
|
||||
}
|
||||
|
||||
/// <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,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
@@ -11,7 +13,7 @@ using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash_Essentials_Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
@@ -48,7 +50,71 @@ namespace PepperDash.Essentials
|
||||
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||
|
||||
//************************
|
||||
|
||||
|
||||
public override string SourceListKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SourceListKey;
|
||||
}
|
||||
set
|
||||
{
|
||||
_SourceListKey = value;
|
||||
SetCodecExternalSources();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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; }
|
||||
@@ -69,31 +135,59 @@ namespace PepperDash.Essentials
|
||||
/// If room is off, enables power on to last source. Default true
|
||||
/// </summary>
|
||||
public bool EnablePowerOnToLastSource { get; set; }
|
||||
private string _lastSourceKey;
|
||||
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;
|
||||
|
||||
/// <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);
|
||||
|
||||
@@ -104,7 +198,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
}
|
||||
private SourceListItem _currentSourceInfo;
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
|
||||
@@ -119,7 +213,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||
|
||||
private readonly CCriticalSection _sourceSelectLock = new CCriticalSection();
|
||||
CCriticalSection SourceSelectLock = new CCriticalSection();
|
||||
|
||||
public EssentialsHuddleVtc1Room(DeviceConfig config)
|
||||
: base(config)
|
||||
@@ -138,7 +232,7 @@ namespace PepperDash.Essentials
|
||||
throw new ArgumentNullException("codec cannot be null");
|
||||
|
||||
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
||||
AudioCodecBase;
|
||||
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
|
||||
if (AudioCodec == null)
|
||||
Debug.Console(0, this, "No Audio Codec Found");
|
||||
|
||||
@@ -156,8 +250,8 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DefaultAudioDevice != null)
|
||||
DefaultVolumeControls = DefaultAudioDevice;
|
||||
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
@@ -166,8 +260,8 @@ namespace PepperDash.Essentials
|
||||
// Combines call feedback from both codecs if available
|
||||
InCallFeedback = new BoolFeedback(() =>
|
||||
{
|
||||
var inAudioCall = false;
|
||||
var inVideoCall = false;
|
||||
bool inAudioCall = false;
|
||||
bool inVideoCall = false;
|
||||
|
||||
if (AudioCodec != null)
|
||||
inAudioCall = AudioCodec.IsInCall;
|
||||
@@ -175,16 +269,56 @@ namespace PepperDash.Essentials
|
||||
if (VideoCodec != null)
|
||||
inVideoCall = VideoCodec.IsInCall;
|
||||
|
||||
return inAudioCall || inVideoCall;
|
||||
if (inAudioCall || inVideoCall)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||
if (dispTwoWay != null)
|
||||
{
|
||||
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (dispTwoWay.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
|
||||
MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
|
||||
|
||||
// Get emergency object, if any
|
||||
Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Emergency Config evaluated.");
|
||||
|
||||
@@ -193,31 +327,19 @@ namespace PepperDash.Essentials
|
||||
VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); };
|
||||
|
||||
if (AudioCodec != null)
|
||||
AudioCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
|
||||
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
|
||||
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => IsSharingFeedback.FireUpdate();
|
||||
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
|
||||
|
||||
// link privacy to VC (for now?)
|
||||
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => PrivacyModeIsOnFeedback.FireUpdate();
|
||||
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.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)
|
||||
{
|
||||
@@ -225,50 +347,6 @@ 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());
|
||||
@@ -285,7 +363,7 @@ namespace PepperDash.Essentials
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
|
||||
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
}
|
||||
|
||||
@@ -344,9 +422,9 @@ namespace PepperDash.Essentials
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
public override void RunRouteAction(string routeKey)
|
||||
public void RunRouteAction(string routeKey)
|
||||
{
|
||||
RunRouteAction(routeKey, () => { });
|
||||
RunRouteAction(routeKey, new Action(() => { }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -354,7 +432,8 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="souceListKey"></param>
|
||||
public void RunRouteAction(string routeKey, string souceListKey)
|
||||
/// <param name="successCallback"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceListKey))
|
||||
{
|
||||
@@ -384,18 +463,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>
|
||||
/// <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
|
||||
CrestronInvoke.BeginInvoke(o =>
|
||||
new CTimer(o =>
|
||||
{
|
||||
// try to prevent multiple simultaneous selections
|
||||
_sourceSelectLock.TryEnter();
|
||||
SourceSelectLock.TryEnter();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -417,9 +496,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
|
||||
@@ -439,7 +518,7 @@ namespace PepperDash.Essentials
|
||||
if (routeKey.ToLower() != "roomoff")
|
||||
{
|
||||
|
||||
_lastSourceKey = routeKey;
|
||||
LastSourceKey = routeKey;
|
||||
}
|
||||
else
|
||||
CurrentSourceInfoKey = null;
|
||||
@@ -491,7 +570,7 @@ namespace PepperDash.Essentials
|
||||
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||
{
|
||||
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
var vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
|
||||
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
|
||||
vd.SetVolume(vol);
|
||||
}
|
||||
}
|
||||
@@ -535,7 +614,7 @@ namespace PepperDash.Essentials
|
||||
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||
}
|
||||
|
||||
_sourceSelectLock.Leave();
|
||||
SourceSelectLock.Leave();
|
||||
}, 0); // end of CTimer
|
||||
}
|
||||
|
||||
@@ -566,9 +645,9 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
private bool DoRoute(SourceRouteListItem route)
|
||||
bool DoRoute(SourceRouteListItem route)
|
||||
{
|
||||
IRoutingSink dest;
|
||||
IRoutingSink dest = null;
|
||||
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
|
||||
@@ -623,9 +702,9 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public override void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
if (!EnablePowerOnToLastSource || _lastSourceKey == null)
|
||||
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||
return;
|
||||
RunRouteAction(_lastSourceKey);
|
||||
RunRouteAction(LastSourceKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -636,13 +715,7 @@ namespace PepperDash.Essentials
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
{
|
||||
var essentialsHuddleSpaceRoom = room as EssentialsHuddleSpaceRoom;
|
||||
if (essentialsHuddleSpaceRoom != null)
|
||||
{
|
||||
essentialsHuddleSpaceRoom.RunRouteAction("roomOff");
|
||||
}
|
||||
}
|
||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
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;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
@@ -13,7 +23,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
public Dictionary<eSourceListItemDestinationTypes, IRoutingSinkWithSwitching> Displays { get; protected set;}
|
||||
|
||||
protected EssentialsNDisplayRoomBase(DeviceConfig config)
|
||||
public EssentialsNDisplayRoomBase(DeviceConfig config)
|
||||
: base (config)
|
||||
{
|
||||
Displays = new Dictionary<eSourceListItemDestinationTypes, IRoutingSinkWithSwitching>();
|
||||
|
||||
435
PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
Normal file
435
PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
Normal file
@@ -0,0 +1,435 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
using PepperDash.Essentials.Devices.Common;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction
|
||||
{
|
||||
private readonly EssentialsTechRoomConfig _config;
|
||||
private readonly Dictionary<string, TwoWayDisplayBase> _displays;
|
||||
|
||||
private readonly DevicePresetsModel _tunerPresets;
|
||||
private readonly Dictionary<string, IRSetTopBoxBase> _tuners;
|
||||
|
||||
private Dictionary<string, string> _currentPresets;
|
||||
private ScheduledEventGroup _roomScheduledEventGroup;
|
||||
|
||||
public EssentialsTechRoom(DeviceConfig config) : base(config)
|
||||
{
|
||||
_config = config.Properties.ToObject<EssentialsTechRoomConfig>();
|
||||
|
||||
_tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName);
|
||||
|
||||
_tunerPresets.SetFileName(_config.PresetsFileName);
|
||||
|
||||
_tunerPresets.PresetRecalled += TunerPresetsOnPresetRecalled;
|
||||
|
||||
_tuners = GetDevices<IRSetTopBoxBase>(_config.Tuners);
|
||||
_displays = GetDevices<TwoWayDisplayBase>(_config.Displays);
|
||||
|
||||
RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn);
|
||||
|
||||
SetUpTunerPresetsFeedback();
|
||||
|
||||
SubscribeToDisplayFeedbacks();
|
||||
|
||||
CreateOrUpdateScheduledEvents();
|
||||
}
|
||||
|
||||
public Dictionary<string, StringFeedback> CurrentPresetsFeedbacks { get; private set; }
|
||||
|
||||
public Dictionary<string, IRSetTopBoxBase> Tuners
|
||||
{
|
||||
get { return _tuners; }
|
||||
}
|
||||
|
||||
public Dictionary<string, TwoWayDisplayBase> Displays
|
||||
{
|
||||
get { return _displays; }
|
||||
}
|
||||
|
||||
public BoolFeedback RoomPowerIsOnFeedback { get; private set; }
|
||||
|
||||
public bool RoomPowerIsOn
|
||||
{
|
||||
get { return _displays.All(kv => kv.Value.PowerIsOnFeedback.BoolValue); }
|
||||
}
|
||||
|
||||
#region ITvPresetsProvider Members
|
||||
|
||||
public DevicePresetsModel TvPresets
|
||||
{
|
||||
get { return _tunerPresets; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
|
||||
{
|
||||
if (!_currentPresets.ContainsKey(device.Key))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_currentPresets[device.Key] = channel;
|
||||
|
||||
if (!CurrentPresetsFeedbacks.ContainsKey(device.Key))
|
||||
{
|
||||
CurrentPresetsFeedbacks[device.Key].FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetUpTunerPresetsFeedback()
|
||||
{
|
||||
_currentPresets = new Dictionary<string, string>();
|
||||
CurrentPresetsFeedbacks = new Dictionary<string, StringFeedback>();
|
||||
|
||||
foreach (var setTopBox in _tuners)
|
||||
{
|
||||
var tuner = setTopBox.Value;
|
||||
_currentPresets.Add(tuner.Key, String.Empty);
|
||||
CurrentPresetsFeedbacks.Add(tuner.Key, new StringFeedback(() => _currentPresets[tuner.Key]));
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribeToDisplayFeedbacks()
|
||||
{
|
||||
foreach (var display in _displays)
|
||||
{
|
||||
display.Value.PowerIsOnFeedback.OutputChange +=
|
||||
(sender, args) => RoomPowerIsOnFeedback.InvokeFireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateOrUpdateScheduledEvents()
|
||||
{
|
||||
var eventsConfig = _config.ScheduledEvents;
|
||||
|
||||
GetOrCreateScheduleGroup();
|
||||
|
||||
foreach (var eventConfig in eventsConfig)
|
||||
{
|
||||
CreateOrUpdateSingleEvent(eventConfig);
|
||||
}
|
||||
|
||||
_roomScheduledEventGroup.UserGroupCallBack += HandleScheduledEvent;
|
||||
}
|
||||
|
||||
private void GetOrCreateScheduleGroup()
|
||||
{
|
||||
if (_roomScheduledEventGroup == null)
|
||||
{
|
||||
_roomScheduledEventGroup = Scheduler.GetEventGroup(Key) ?? new ScheduledEventGroup(Key);
|
||||
|
||||
Scheduler.AddEventGroup(_roomScheduledEventGroup);
|
||||
}
|
||||
|
||||
_roomScheduledEventGroup.RetrieveAllEvents();
|
||||
}
|
||||
|
||||
private void CreateOrUpdateSingleEvent(ScheduledEventConfig scheduledEvent)
|
||||
{
|
||||
if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(scheduledEvent.Key))
|
||||
{
|
||||
SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
var roomEvent = _roomScheduledEventGroup.ScheduledEvents[scheduledEvent.Key];
|
||||
|
||||
if (!SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) &&
|
||||
!SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this,
|
||||
"Existing event does not match new config properties. Deleting existing event '{0}' and creating new event from configuration",
|
||||
roomEvent.Name);
|
||||
|
||||
_roomScheduledEventGroup.DeleteEvent(roomEvent);
|
||||
|
||||
SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
|
||||
}
|
||||
|
||||
public void AddOrUpdateScheduledEvent(ScheduledEventConfig scheduledEvent)
|
||||
{
|
||||
//update config based on key of scheduleEvent
|
||||
GetOrCreateScheduleGroup();
|
||||
var existingEventIndex = _config.ScheduledEvents.FindIndex((e) => e.Key == scheduledEvent.Key);
|
||||
|
||||
if (existingEventIndex < 0)
|
||||
{
|
||||
_config.ScheduledEvents.Add(scheduledEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
_config.ScheduledEvents[existingEventIndex] = scheduledEvent;
|
||||
}
|
||||
|
||||
//create or update event based on config
|
||||
CreateOrUpdateSingleEvent(scheduledEvent);
|
||||
//save config
|
||||
Config.Properties = JToken.FromObject(_config);
|
||||
|
||||
CustomSetConfig(Config);
|
||||
//Fire Event
|
||||
OnScheduledEventUpdate();
|
||||
}
|
||||
|
||||
public List<ScheduledEventConfig> GetScheduledEvents()
|
||||
{
|
||||
return _config.ScheduledEvents ?? new List<ScheduledEventConfig>();
|
||||
}
|
||||
|
||||
private void OnScheduledEventUpdate()
|
||||
{
|
||||
var handler = ScheduledEventsChanged;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(this, new ScheduledEventEventArgs {ScheduledEvents = _config.ScheduledEvents});
|
||||
}
|
||||
|
||||
public event EventHandler<ScheduledEventEventArgs> ScheduledEventsChanged;
|
||||
|
||||
private void HandleScheduledEvent(ScheduledEvent schevent, ScheduledEventCommon.eCallbackReason type)
|
||||
{
|
||||
var eventConfig = _config.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name);
|
||||
|
||||
if (eventConfig == null)
|
||||
{
|
||||
Debug.Console(1, this, "Event with name {0} not found", schevent.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Running actions for event {0}", schevent.Name);
|
||||
|
||||
if (eventConfig.Acknowledgeable)
|
||||
{
|
||||
schevent.Acknowledge();
|
||||
}
|
||||
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
foreach (var a in eventConfig.Actions)
|
||||
{
|
||||
DeviceJsonApi.DoDeviceAction(a);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void RoomPowerOn()
|
||||
{
|
||||
var dummySource = DeviceManager.GetDeviceForKey(_config.DummySourceKey) as IRoutingOutputs;
|
||||
|
||||
if (dummySource == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to get source with key: {0}", _config.DummySourceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var display in _displays)
|
||||
{
|
||||
RunDirectRoute(dummySource, display.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public void RoomPowerOff()
|
||||
{
|
||||
foreach (var display in _displays)
|
||||
{
|
||||
display.Value.PowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, T> GetDevices<T>(ICollection<string> config) where T : IKeyed
|
||||
{
|
||||
try
|
||||
{
|
||||
var returnValue = DeviceManager.AllDevices.OfType<T>()
|
||||
.Where(d => config.Contains(d.Key))
|
||||
.ToDictionary(d => d.Key, d => d);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
|
||||
"Error getting devices. Check Essentials Configuration");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsRoomBase
|
||||
|
||||
protected override Func<bool> IsWarmingFeedbackFunc
|
||||
{
|
||||
get { return () => false; }
|
||||
}
|
||||
|
||||
protected override Func<bool> IsCoolingFeedbackFunc
|
||||
{
|
||||
get { return () => false; }
|
||||
}
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
get { return () => RoomPowerIsOn; }
|
||||
}
|
||||
|
||||
protected override void EndShutdown()
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetDefaultLevels()
|
||||
{
|
||||
}
|
||||
|
||||
public override void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool RunDefaultPresentRoute()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IBridgeAdvanced
|
||||
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
|
||||
var joinMap = new EssentialsTechRoomJoinMap(joinStart);
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!String.IsNullOrEmpty(joinMapSerialized))
|
||||
{
|
||||
joinMap = JsonConvert.DeserializeObject<EssentialsTechRoomJoinMap>(joinMapSerialized);
|
||||
}
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
uint i;
|
||||
if (_config.IsPrimary)
|
||||
{
|
||||
i = 0;
|
||||
foreach (var feedback in CurrentPresetsFeedbacks)
|
||||
{
|
||||
feedback.Value.LinkInputSig(trilist.StringInput[(uint) (joinMap.CurrentPreset.JoinNumber + i)]);
|
||||
i++;
|
||||
}
|
||||
|
||||
trilist.OnlineStatusChange += (device, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var feedback in CurrentPresetsFeedbacks)
|
||||
{
|
||||
feedback.Value.FireUpdate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
i = 0;
|
||||
foreach (var setTopBox in _tuners)
|
||||
{
|
||||
var tuner = setTopBox;
|
||||
|
||||
trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private class EssentialsTechRoomJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("currentPreset")]
|
||||
public JoinDataComplete CurrentPreset = new JoinDataComplete(new JoinData {JoinNumber = 1, JoinSpan = 16},
|
||||
new JoinMetadata {Description = "Current Tuner Preset", JoinType = eJoinType.Serial});
|
||||
|
||||
public EssentialsTechRoomJoinMap(uint joinStart) : base(joinStart, typeof(EssentialsTechRoomJoinMap))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#region IRunDirectRouteAction Members
|
||||
|
||||
private void RunDirectRoute(IRoutingOutputs source, IRoutingSink dest)
|
||||
{
|
||||
if (dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", dest.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IHasPowerControl)
|
||||
(dest as IHasPowerControl).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
dest.ReleaseAndMakeRoute(source, eRoutingSignalType.Video);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to route directly between a source and destination
|
||||
/// </summary>
|
||||
/// <param name="sourceKey"></param>
|
||||
/// <param name="destinationKey"></param>
|
||||
public void RunDirectRoute(string sourceKey, string destinationKey)
|
||||
{
|
||||
IRoutingSink dest = null;
|
||||
|
||||
dest = DeviceManager.GetDeviceForKey(destinationKey) as IRoutingSink;
|
||||
|
||||
var source = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs;
|
||||
|
||||
if (source == null || dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route unknown source or destination '{0}' to {1}", sourceKey, destinationKey);
|
||||
return;
|
||||
}
|
||||
RunDirectRoute(source, dest);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class ScheduledEventEventArgs : EventArgs
|
||||
{
|
||||
public List<ScheduledEventConfig> ScheduledEvents;
|
||||
}
|
||||
}
|
||||
@@ -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(Core.Rooms.Config.EssentialsEnvironmentPropertiesConfig EnvironmentPropertiesConfig)
|
||||
public void GetDevicesFromConfig(Room.Config.EssentialsEnvironmentPropertiesConfig EnvironmentPropertiesConfig)
|
||||
{
|
||||
if (EnvironmentPropertiesConfig != null)
|
||||
{
|
||||
|
||||
@@ -10,11 +10,10 @@ 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.Core.Rooms.Config;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
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
|
||||
{
|
||||
@@ -15,18 +17,13 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public class EssentialsHuddlePanelAvFunctionsDriver : PanelDriverBase, IAVDriver
|
||||
{
|
||||
private readonly CrestronTouchpanelPropertiesConfig _config;
|
||||
CrestronTouchpanelPropertiesConfig Config;
|
||||
|
||||
public enum UiDisplayMode
|
||||
{
|
||||
PresentationMode, AudioSetup
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The parent driver for this
|
||||
/// </summary>
|
||||
public PanelDriverBase Parent { get; private set; }
|
||||
|
||||
public uint StartPageVisibleJoin { get; private set; }
|
||||
|
||||
|
||||
@@ -41,8 +38,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>
|
||||
@@ -50,8 +47,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>
|
||||
@@ -59,12 +56,21 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public uint PowerOffTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DefaultRoomKey { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DefaultRoomKey
|
||||
{
|
||||
get { return _DefaultRoomKey; }
|
||||
set
|
||||
{
|
||||
_DefaultRoomKey = value;
|
||||
//CurrentRoom = DeviceManager.GetDeviceForKey(value) as EssentialsHuddleSpaceRoom;
|
||||
}
|
||||
}
|
||||
string _DefaultRoomKey;
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Indicates that the SetHeaderButtons method has completed successfully
|
||||
/// </summary>
|
||||
public bool HeaderButtonsAreSetUp { get; private set; }
|
||||
@@ -74,13 +80,13 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public EssentialsHuddleSpaceRoom CurrentRoom
|
||||
{
|
||||
get { return _currentRoom; }
|
||||
get { return _CurrentRoom; }
|
||||
set
|
||||
{
|
||||
SetCurrentRoom(value);
|
||||
}
|
||||
}
|
||||
EssentialsHuddleSpaceRoom _currentRoom;
|
||||
EssentialsHuddleSpaceRoom _CurrentRoom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -90,86 +96,88 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// For hitting feedback
|
||||
/// </summary>
|
||||
private readonly BoolInputSig _shareButtonSig;
|
||||
private BoolInputSig _endMeetingButtonSig;
|
||||
BoolInputSig ShareButtonSig;
|
||||
BoolInputSig EndMeetingButtonSig;
|
||||
|
||||
/// <summary>
|
||||
/// Controls the extended period that the volume gauge shows on-screen,
|
||||
/// as triggered by Volume up/down operations
|
||||
/// </summary>
|
||||
private readonly BoolFeedbackPulseExtender _volumeGaugeFeedback;
|
||||
BoolFeedbackPulseExtender VolumeGaugeFeedback;
|
||||
|
||||
/// <summary>
|
||||
/// Controls the period that the volume buttons show on non-hard-button
|
||||
/// interfaces
|
||||
/// </summary>
|
||||
private readonly BoolFeedbackPulseExtender _volumeButtonsPopupFeedback;
|
||||
BoolFeedbackPulseExtender VolumeButtonsPopupFeedback;
|
||||
|
||||
/// <summary>
|
||||
/// The parent driver for this
|
||||
/// </summary>
|
||||
private readonly PanelDriverBase _parent;
|
||||
public PanelDriverBase Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// All children attached to this driver. For hiding and showing as a group.
|
||||
/// </summary>
|
||||
private List<PanelDriverBase> _childDrivers = new List<PanelDriverBase>();
|
||||
List<PanelDriverBase> ChildDrivers = new List<PanelDriverBase>();
|
||||
|
||||
private readonly List<BoolInputSig> _currentDisplayModeSigsInUse = new List<BoolInputSig>();
|
||||
List<BoolInputSig> CurrentDisplayModeSigsInUse = new List<BoolInputSig>();
|
||||
|
||||
//// Important smart objects
|
||||
|
||||
/// <summary>
|
||||
/// Smart Object 3200
|
||||
/// </summary>
|
||||
private readonly SubpageReferenceList _sourcesSrl;
|
||||
SubpageReferenceList SourcesSrl;
|
||||
|
||||
/// <summary>
|
||||
/// Smart Object 15022
|
||||
/// </summary>
|
||||
private readonly SubpageReferenceList _activityFooterSrl;
|
||||
SubpageReferenceList ActivityFooterSrl;
|
||||
|
||||
/// <summary>
|
||||
/// Tracks which audio page group the UI is in
|
||||
/// </summary>
|
||||
private UiDisplayMode _currentDisplayMode;
|
||||
UiDisplayMode CurrentDisplayMode;
|
||||
|
||||
/// <summary>
|
||||
/// The AV page mangagers that have been used, to keep them alive for later
|
||||
/// </summary>
|
||||
private readonly Dictionary<object, PageManager> _pageManagers = new Dictionary<object, PageManager>();
|
||||
Dictionary<object, PageManager> PageManagers = new Dictionary<object, PageManager>();
|
||||
|
||||
/// <summary>
|
||||
/// Current page manager running for a source
|
||||
/// </summary>
|
||||
private PageManager _currentSourcePageManager;
|
||||
PageManager CurrentSourcePageManager;
|
||||
|
||||
/// <summary>
|
||||
/// Will auto-timeout a power off
|
||||
/// </summary>
|
||||
private CTimer _powerOffTimer;
|
||||
CTimer PowerOffTimer;
|
||||
|
||||
private ModalDialog _powerDownModal;
|
||||
ModalDialog PowerDownModal;
|
||||
|
||||
public JoinedSigInterlock PopupInterlock { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The driver for the tech page. Lazy getter for memory usage
|
||||
/// </summary>
|
||||
EssentialsHuddleTechPageDriver TechDriver
|
||||
PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver TechDriver
|
||||
{
|
||||
get {
|
||||
return _techDriver ??
|
||||
(_techDriver = new EssentialsHuddleTechPageDriver(TriList, CurrentRoom.PropertiesConfig.Tech));
|
||||
get
|
||||
{
|
||||
if (_TechDriver == null)
|
||||
_TechDriver = new PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver(TriList, CurrentRoom.PropertiesConfig.Tech);
|
||||
return _TechDriver;
|
||||
}
|
||||
}
|
||||
private EssentialsHuddleTechPageDriver _techDriver;
|
||||
PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver _TechDriver;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Controls timeout of notification ribbon timer
|
||||
/// </summary>
|
||||
private CTimer _ribbonTimer;
|
||||
CTimer RibbonTimer;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
@@ -177,25 +185,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;
|
||||
@@ -216,28 +224,9 @@ namespace PepperDash.Essentials
|
||||
return;
|
||||
}
|
||||
|
||||
switch (_config.HeaderStyle.ToLower())
|
||||
{
|
||||
case CrestronTouchpanelPropertiesConfig.Habanero:
|
||||
TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, (() =>
|
||||
{
|
||||
if (CurrentRoom.IsMobileControlEnabled)
|
||||
{
|
||||
Debug.Console(1, "Showing Mobile Control Header Info");
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoMCPageVisible);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, "Showing Non Mobile Control Header Info");
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoPageVisible);
|
||||
}
|
||||
}));
|
||||
break;
|
||||
case CrestronTouchpanelPropertiesConfig.Verbose:
|
||||
break;
|
||||
}
|
||||
var roomConf = CurrentRoom.PropertiesConfig;
|
||||
|
||||
if (_config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Habanero)
|
||||
if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Habanero)
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () =>
|
||||
{
|
||||
@@ -253,7 +242,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (_config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose)
|
||||
else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose)
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () =>
|
||||
{
|
||||
@@ -270,9 +259,9 @@ namespace PepperDash.Essentials
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -359,8 +348,8 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.LogoUrlVisible, true);
|
||||
TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _currentRoom.LogoUrlLightBkgnd);
|
||||
TriList.SetString(UIStringJoin.LogoUrlDarkBkgnd, _currentRoom.LogoUrlDarkBkgnd);
|
||||
TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrlLightBkgnd);
|
||||
TriList.SetString(UIStringJoin.LogoUrlDarkBkgnd, _CurrentRoom.LogoUrlDarkBkgnd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +374,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();
|
||||
@@ -402,12 +391,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);
|
||||
}
|
||||
}
|
||||
@@ -418,10 +407,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,7 +422,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
//Clear whatever is showing now.
|
||||
HideAndClearCurrentDisplayModeSigsInUse();
|
||||
_currentDisplayMode = mode;
|
||||
CurrentDisplayMode = mode;
|
||||
switch (mode)
|
||||
{
|
||||
case UiDisplayMode.PresentationMode:
|
||||
@@ -451,7 +440,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;
|
||||
@@ -460,8 +449,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();
|
||||
@@ -474,12 +463,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>
|
||||
@@ -487,15 +476,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>
|
||||
@@ -503,8 +492,8 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void ShareButtonPressed()
|
||||
{
|
||||
_shareButtonSig.BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
|
||||
ShareButtonSig.BoolValue = true;
|
||||
TriList.BooleanInput[StartPageVisibleJoin].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
|
||||
// Run default source when room is off and share is pressed
|
||||
@@ -518,7 +507,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void ShowCurrentDisplayModeSigsInUse()
|
||||
{
|
||||
foreach (var sig in _currentDisplayModeSigsInUse)
|
||||
foreach (var sig in CurrentDisplayModeSigsInUse)
|
||||
sig.BoolValue = true;
|
||||
}
|
||||
|
||||
@@ -527,9 +516,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>
|
||||
@@ -537,7 +526,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public override void BackButtonPressed()
|
||||
{
|
||||
switch (_currentDisplayMode)
|
||||
switch (CurrentDisplayMode)
|
||||
{
|
||||
case UiDisplayMode.PresentationMode:
|
||||
//CancelReturnToSourceTimer();
|
||||
@@ -552,7 +541,7 @@ namespace PepperDash.Essentials
|
||||
void BackToHome()
|
||||
{
|
||||
Hide();
|
||||
_parent.Show();
|
||||
Parent.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -564,28 +553,26 @@ namespace PepperDash.Essentials
|
||||
return;
|
||||
|
||||
var uiDev = CurrentRoom.CurrentSourceInfo.SourceDevice as IUiDisplayInfo;
|
||||
// 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();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -596,7 +583,7 @@ namespace PepperDash.Essentials
|
||||
void UiSelectSource(string key)
|
||||
{
|
||||
// Run the route and when it calls back, show the source
|
||||
CurrentRoom.RunRouteAction(key, () => { });
|
||||
CurrentRoom.RunRouteAction(key, new Action(() => { }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -620,12 +607,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
|
||||
@@ -639,15 +626,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
|
||||
@@ -665,7 +652,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;
|
||||
}
|
||||
@@ -677,10 +664,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;
|
||||
@@ -688,38 +675,27 @@ 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", stringFeedback.StringValue);
|
||||
var message = string.Format("Meeting will end in {0} seconds", (sender as StringFeedback).StringValue);
|
||||
TriList.StringInput[ModalDialog.MessageTextJoin].StringValue = message;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
void ShutdownPromptTimer_PercentFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
var value = (ushort)((sender as IntFeedback).UShortValue * 65535 / 100);
|
||||
TriList.UShortInput[ModalDialog.TimerGaugeJoin].UShortValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void CancelPowerOffTimer()
|
||||
{
|
||||
if (_powerOffTimer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_powerOffTimer.Stop();
|
||||
_powerOffTimer = null;
|
||||
if (PowerOffTimer != null)
|
||||
{
|
||||
PowerOffTimer.Stop();
|
||||
PowerOffTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -727,13 +703,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,8 +721,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);
|
||||
}
|
||||
@@ -759,8 +735,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);
|
||||
}
|
||||
@@ -771,31 +747,31 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public void RefreshCurrentRoom(EssentialsHuddleSpaceRoom room)
|
||||
{
|
||||
if (_currentRoom != null)
|
||||
if (_CurrentRoom != null)
|
||||
{
|
||||
// Disconnect current room
|
||||
_currentRoom.CurrentVolumeDeviceChange -= CurrentRoom_CurrentAudioDeviceChange;
|
||||
_CurrentRoom.CurrentVolumeDeviceChange -= this.CurrentRoom_CurrentAudioDeviceChange;
|
||||
ClearAudioDeviceConnections();
|
||||
_currentRoom.CurrentSourceChange -= CurrentRoom_SourceInfoChange;
|
||||
DisconnectSource(_currentRoom.CurrentSourceInfo);
|
||||
_currentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted;
|
||||
_currentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished;
|
||||
_currentRoom.ShutdownPromptTimer.WasCancelled -= ShutdownPromptTimer_WasCancelled;
|
||||
_CurrentRoom.CurrentSourceChange -= this.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)
|
||||
@@ -812,16 +788,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.LogoUrlLightBkgnd == null)
|
||||
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _CurrentRoom.Name;
|
||||
if (_CurrentRoom.LogoUrlLightBkgnd == null)
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = false;
|
||||
@@ -830,33 +806,28 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = true;
|
||||
TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _currentRoom.LogoUrlLightBkgnd;
|
||||
TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _currentRoom.LogoUrlDarkBkgnd;
|
||||
TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _CurrentRoom.LogoUrlLightBkgnd;
|
||||
TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _CurrentRoom.LogoUrlDarkBkgnd;
|
||||
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
var essentialsPanelMainInterfaceDriver = _parent as EssentialsPanelMainInterfaceDriver;
|
||||
|
||||
if (essentialsPanelMainInterfaceDriver != null)
|
||||
{
|
||||
essentialsPanelMainInterfaceDriver.HeaderDriver.SetupHeaderButtons(this, CurrentRoom);
|
||||
}
|
||||
(Parent as EssentialsPanelMainInterfaceDriver).HeaderDriver.SetupHeaderButtons(this, CurrentRoom);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -867,11 +838,11 @@ namespace PepperDash.Essentials
|
||||
|
||||
void SetCurrentRoom(EssentialsHuddleSpaceRoom room)
|
||||
{
|
||||
if (_currentRoom == room) return;
|
||||
if (_CurrentRoom == room) return;
|
||||
// Disconnect current (probably never called)
|
||||
|
||||
if (_currentRoom != null)
|
||||
_currentRoom.ConfigChanged -= room_ConfigChanged;
|
||||
if (_CurrentRoom != null)
|
||||
_CurrentRoom.ConfigChanged -= room_ConfigChanged;
|
||||
|
||||
room.ConfigChanged -= room_ConfigChanged;
|
||||
room.ConfigChanged += room_ConfigChanged;
|
||||
@@ -881,8 +852,8 @@ namespace PepperDash.Essentials
|
||||
StartPageVisibleJoin = UIBoolJoin.StartMCPageVisible;
|
||||
UpdateMCJoins(room);
|
||||
|
||||
if (_currentRoom != null)
|
||||
_currentRoom.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged;
|
||||
if (_CurrentRoom != null)
|
||||
_CurrentRoom.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged;
|
||||
|
||||
room.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged;
|
||||
room.MobileControlRoomBridge.UserCodeChanged += MobileControlRoomBridge_UserCodeChanged;
|
||||
@@ -897,7 +868,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
void MobileControlRoomBridge_UserCodeChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateMCJoins(_currentRoom);
|
||||
UpdateMCJoins(_CurrentRoom);
|
||||
}
|
||||
|
||||
void UpdateMCJoins(EssentialsHuddleSpaceRoom room)
|
||||
@@ -914,7 +885,7 @@ namespace PepperDash.Essentials
|
||||
/// <param name="e"></param>
|
||||
void room_ConfigChanged(object sender, EventArgs e)
|
||||
{
|
||||
RefreshCurrentRoom(_currentRoom);
|
||||
RefreshCurrentRoom(_CurrentRoom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -927,7 +898,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;
|
||||
|
||||
@@ -989,14 +960,15 @@ namespace PepperDash.Essentials
|
||||
// Hide whatever is showing
|
||||
if (IsVisible)
|
||||
{
|
||||
if (_currentSourcePageManager != null)
|
||||
if (CurrentSourcePageManager != null)
|
||||
{
|
||||
_currentSourcePageManager.Hide();
|
||||
_currentSourcePageManager = null;
|
||||
CurrentSourcePageManager.Hide();
|
||||
CurrentSourcePageManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
var previousDev = previousInfo.SourceDevice;
|
||||
if (previousInfo == null) return;
|
||||
var previousDev = previousInfo.SourceDevice;
|
||||
|
||||
// device type interfaces
|
||||
if (previousDev is ISetTopBoxControls)
|
||||
@@ -1027,7 +999,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
var routeInfo = CurrentRoom.CurrentSourceInfo;
|
||||
// This will show off popup too
|
||||
if (IsVisible)
|
||||
if (this.IsVisible)
|
||||
ShowCurrentSource();
|
||||
|
||||
if (routeInfo == null)// || !CurrentRoom.OnFeedback.BoolValue)
|
||||
@@ -1035,23 +1007,22 @@ 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";
|
||||
Hide();
|
||||
_parent.Show();
|
||||
this.Hide();
|
||||
Parent.Show();
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
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 (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.Core.Rooms.Config;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials.UIDrivers
|
||||
{
|
||||
|
||||
@@ -8,9 +8,9 @@ using Crestron.SimplSharpPro.UI;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices.Codec;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.PageManagers;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
|
||||
@@ -93,15 +93,15 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
SubpageReferenceList ActivityFooterSrl;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SubpageReferenceList MeetingOrContactMethodModalSrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of buttons on the header. Managed with visibility only
|
||||
/// </summary>
|
||||
//SmartObjectHeaderButtonList HeaderButtonsList;
|
||||
/// <summary>
|
||||
/// The list of buttons on the header. Managed with visibility only
|
||||
/// </summary>
|
||||
//SmartObjectHeaderButtonList HeaderButtonsList;
|
||||
|
||||
/// <summary>
|
||||
/// The AV page mangagers that have been used, to keep them alive for later
|
||||
@@ -126,7 +126,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
//ModalDialog WarmingCoolingModal;
|
||||
//ModalDialog WarmingCoolingModal;
|
||||
|
||||
/// <summary>
|
||||
/// Represents
|
||||
@@ -178,12 +178,12 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
UiDisplayMode CurrentMode = UiDisplayMode.Start;
|
||||
|
||||
CTimer NextMeetingTimer;
|
||||
CTimer NextMeetingTimer;
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the last meeting that was cancelled
|
||||
/// </summary>
|
||||
string LastMeetingDismissedId;
|
||||
/// <summary>
|
||||
/// Tracks the last meeting that was cancelled
|
||||
/// </summary>
|
||||
string LastMeetingDismissedId;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
@@ -205,11 +205,11 @@ namespace PepperDash.Essentials
|
||||
ShareButtonSig = ActivityFooterSrl.BoolInputSig(1, 1);
|
||||
EndMeetingButtonSig = ActivityFooterSrl.BoolInputSig(3, 1);
|
||||
|
||||
MeetingOrContactMethodModalSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.MeetingListSRL, 3, 3, 5);
|
||||
MeetingOrContactMethodModalSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.MeetingListSRL, 3, 3, 5);
|
||||
|
||||
|
||||
// buttons are added in SetCurrentRoom
|
||||
//HeaderButtonsList = new SmartObjectHeaderButtonList(TriList.SmartObjects[UISmartObjectJoin.HeaderButtonList]);
|
||||
// buttons are added in SetCurrentRoom
|
||||
//HeaderButtonsList = new SmartObjectHeaderButtonList(TriList.SmartObjects[UISmartObjectJoin.HeaderButtonList]);
|
||||
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
|
||||
@@ -245,17 +245,17 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
if (CurrentRoom.IsMobileControlEnabled)
|
||||
{
|
||||
Debug.Console(1, "Showing Mobile Control Header Info");
|
||||
Debug.Console(1, "Showing Mobile Control Header Info");
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoMCPageVisible);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, "Showing Non Mobile Control Header Info");
|
||||
Debug.Console(1, "Showing Non Mobile Control Header Info");
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoPageVisible);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose)
|
||||
else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose)
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () =>
|
||||
{
|
||||
@@ -276,7 +276,7 @@ namespace PepperDash.Essentials
|
||||
TriList.SetBool(UIBoolJoin.DateOnlyVisible, Config.ShowDate && !Config.ShowTime);
|
||||
TriList.SetBool(UIBoolJoin.TimeOnlyVisible, !Config.ShowDate && Config.ShowTime);
|
||||
|
||||
TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true);
|
||||
TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true);
|
||||
|
||||
TriList.SetBool(UIBoolJoin.ActivityFooterVisible, true);
|
||||
|
||||
@@ -288,29 +288,29 @@ namespace PepperDash.Essentials
|
||||
if (CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.TapToBeginVisible, false);
|
||||
SetupActivityFooterWhenRoomOn();
|
||||
SetupActivityFooterWhenRoomOn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetBool(StartPageVisibleJoin, true);
|
||||
TriList.SetBool(UIBoolJoin.TapToBeginVisible, true);
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
}
|
||||
ShowCurrentDisplayModeSigsInUse();
|
||||
|
||||
// *** Header Buttons ***
|
||||
|
||||
|
||||
// Generic "close" button for popup modals
|
||||
TriList.SetSigFalseAction(UIBoolJoin.InterlockedModalClosePress, PopupInterlock.HideAndClear);
|
||||
|
||||
// Volume related things
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VolumeDefaultPress, () => CurrentRoom.SetDefaultLevels());
|
||||
TriList.SetString(UIStringJoin.AdvancedVolumeSlider1Text, "Room");
|
||||
|
||||
//if (TriList is CrestronApp)
|
||||
// TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = false;
|
||||
//else
|
||||
// TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = true;
|
||||
|
||||
//if (TriList is CrestronApp)
|
||||
// TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = false;
|
||||
//else
|
||||
// TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = true;
|
||||
|
||||
// power-related functions
|
||||
// Note: some of these are not directly-related to the huddle space UI, but are held over
|
||||
@@ -323,7 +323,7 @@ namespace PepperDash.Essentials
|
||||
(CurrentRoom.DefaultDisplay as IHasPowerControl).PowerToggle();
|
||||
});
|
||||
|
||||
SetupNextMeetingTimer();
|
||||
SetupNextMeetingTimer();
|
||||
|
||||
base.Show();
|
||||
}
|
||||
@@ -333,12 +333,12 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public void ShowActiveCallsList()
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.CallEndAllConfirmVisible, true);
|
||||
if (PopupInterlock.CurrentJoin == UIBoolJoin.HeaderActiveCallsListVisible)
|
||||
TriList.SetBool(UIBoolJoin.CallEndAllConfirmVisible, true);
|
||||
if(PopupInterlock.CurrentJoin == UIBoolJoin.HeaderActiveCallsListVisible)
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible);
|
||||
else
|
||||
{
|
||||
if ((CurrentRoom.ScheduleSource as VideoCodecBase).IsInCall)
|
||||
if((CurrentRoom.ScheduleSource as VideoCodecBase).IsInCall)
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible);
|
||||
}
|
||||
}
|
||||
@@ -377,14 +377,14 @@ namespace PepperDash.Essentials
|
||||
public override void Hide()
|
||||
{
|
||||
HideAndClearCurrentDisplayModeSigsInUse();
|
||||
TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, false);
|
||||
TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = false;
|
||||
TriList.BooleanInput[StartPageVisibleJoin].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
if (NextMeetingTimer != null)
|
||||
NextMeetingTimer.Stop();
|
||||
HideNextMeetingPopup();
|
||||
if (NextMeetingTimer != null)
|
||||
NextMeetingTimer.Stop();
|
||||
HideNextMeetingPopup();
|
||||
base.Hide();
|
||||
}
|
||||
|
||||
@@ -401,8 +401,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
if (RibbonTimer != null)
|
||||
RibbonTimer.Stop();
|
||||
RibbonTimer = new CTimer(o =>
|
||||
{
|
||||
RibbonTimer = new CTimer(o => {
|
||||
TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, false);
|
||||
RibbonTimer = null;
|
||||
}, timeout);
|
||||
@@ -422,145 +421,145 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
void SetupNextMeetingTimer()
|
||||
{
|
||||
var ss = CurrentRoom.ScheduleSource;
|
||||
if (ss != null)
|
||||
{
|
||||
NextMeetingTimer = new CTimer(o => ShowNextMeetingTimerCallback(), null, 0, 60000);
|
||||
}
|
||||
}
|
||||
void SetupNextMeetingTimer()
|
||||
{
|
||||
var ss = CurrentRoom.ScheduleSource;
|
||||
if (ss != null)
|
||||
{
|
||||
NextMeetingTimer = new CTimer(o => ShowNextMeetingTimerCallback(), null, 0, 60000);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void ShowNextMeetingTimerCallback()
|
||||
{
|
||||
// Every 60 seconds, refresh the calendar
|
||||
RefreshMeetingsList();
|
||||
// check meetings list for the closest, joinable meeting
|
||||
var ss = CurrentRoom.ScheduleSource;
|
||||
var meetings = ss.CodecSchedule.Meetings;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void ShowNextMeetingTimerCallback()
|
||||
{
|
||||
// Every 60 seconds, refresh the calendar
|
||||
RefreshMeetingsList();
|
||||
// check meetings list for the closest, joinable meeting
|
||||
var ss = CurrentRoom.ScheduleSource;
|
||||
var meetings = ss.CodecSchedule.Meetings;
|
||||
|
||||
if (meetings.Count > 0)
|
||||
{
|
||||
// If the room is off pester the user
|
||||
// If the room is on, and the meeting is joinable
|
||||
// and the LastMeetingDismissed != this meeting
|
||||
if (meetings.Count > 0)
|
||||
{
|
||||
// If the room is off pester the user
|
||||
// If the room is on, and the meeting is joinable
|
||||
// and the LastMeetingDismissed != this meeting
|
||||
|
||||
var lastMeetingDismissed = meetings.FirstOrDefault(m => m.Id == LastMeetingDismissedId);
|
||||
Debug.Console(0, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*",
|
||||
CurrentRoom.OnFeedback.BoolValue,
|
||||
LastMeetingDismissedId,
|
||||
lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToShortTimeString() : "");
|
||||
var lastMeetingDismissed = meetings.FirstOrDefault(m => m.Id == LastMeetingDismissedId);
|
||||
Debug.Console(0, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*",
|
||||
CurrentRoom.OnFeedback.BoolValue,
|
||||
LastMeetingDismissedId,
|
||||
lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToShortTimeString() : "");
|
||||
|
||||
var meeting = meetings.LastOrDefault(m => m.Joinable);
|
||||
if (CurrentRoom.OnFeedback.BoolValue
|
||||
&& lastMeetingDismissed == meeting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var meeting = meetings.LastOrDefault(m => m.Joinable);
|
||||
if (CurrentRoom.OnFeedback.BoolValue
|
||||
&& lastMeetingDismissed == meeting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LastMeetingDismissedId = null;
|
||||
// Clear the popup when we run out of meetings
|
||||
if (meeting == null)
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Upcoming meeting");
|
||||
TriList.SetString(UIStringJoin.NextMeetingStartTimeText, meeting.StartTime.ToShortTimeString());
|
||||
TriList.SetString(UIStringJoin.NextMeetingEndTimeText, meeting.EndTime.ToShortTimeString());
|
||||
TriList.SetString(UIStringJoin.NextMeetingTitleText, meeting.Title);
|
||||
TriList.SetString(UIStringJoin.NextMeetingNameText, meeting.Organizer);
|
||||
TriList.SetString(UIStringJoin.NextMeetingButtonLabel, "Join");
|
||||
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingJoinPress, () =>
|
||||
LastMeetingDismissedId = null;
|
||||
// Clear the popup when we run out of meetings
|
||||
if (meeting == null)
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Upcoming meeting");
|
||||
TriList.SetString(UIStringJoin.NextMeetingStartTimeText, meeting.StartTime.ToShortTimeString());
|
||||
TriList.SetString(UIStringJoin.NextMeetingEndTimeText, meeting.EndTime.ToShortTimeString());
|
||||
TriList.SetString(UIStringJoin.NextMeetingTitleText, meeting.Title);
|
||||
TriList.SetString(UIStringJoin.NextMeetingNameText, meeting.Organizer);
|
||||
TriList.SetString(UIStringJoin.NextMeetingButtonLabel, "Join");
|
||||
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingJoinPress, () =>
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
PopupInterlock.Hide();
|
||||
RoomOnAndDialMeeting(meeting);
|
||||
});
|
||||
TriList.SetString(UIStringJoin.NextMeetingSecondaryButtonLabel, "Show Schedule");
|
||||
TriList.SetSigFalseAction(UIBoolJoin.CalendarHeaderButtonPress, () =>
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
//CalendarPress();
|
||||
RefreshMeetingsList();
|
||||
PopupInterlock.ShowInterlocked(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
||||
});
|
||||
var indexOfNext = meetings.IndexOf(meeting) + 1;
|
||||
|
||||
// indexOf = 3, 4 meetings :
|
||||
if (indexOfNext < meetings.Count)
|
||||
TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText,
|
||||
meetings[indexOfNext].StartTime.ToShortTimeString());
|
||||
else
|
||||
TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, "No more meetings today");
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingModalClosePress, () =>
|
||||
{
|
||||
// Mark the meeting to not re-harass the user
|
||||
if(CurrentRoom.OnFeedback.BoolValue)
|
||||
LastMeetingDismissedId = meeting.Id;
|
||||
HideNextMeetingPopup();
|
||||
});
|
||||
|
||||
TriList.SetBool(UIBoolJoin.NextMeetingModalVisible, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void HideNextMeetingPopup()
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.NextMeetingModalVisible, false);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calendar should only be visible when it's supposed to
|
||||
/// </summary>
|
||||
public void CalendarPress()
|
||||
{
|
||||
//RefreshMeetingsList(); // List should be up-to-date
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dials a meeting after turning on room (if necessary)
|
||||
/// </summary>
|
||||
void RoomOnAndDialMeeting(Meeting meeting)
|
||||
{
|
||||
Action dialAction = () =>
|
||||
{
|
||||
var d = CurrentRoom.ScheduleSource as VideoCodecBase;
|
||||
if (d != null)
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
PopupInterlock.Hide();
|
||||
RoomOnAndDialMeeting(meeting);
|
||||
});
|
||||
TriList.SetString(UIStringJoin.NextMeetingSecondaryButtonLabel, "Show Schedule");
|
||||
TriList.SetSigFalseAction(UIBoolJoin.CalendarHeaderButtonPress, () =>
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
//CalendarPress();
|
||||
RefreshMeetingsList();
|
||||
PopupInterlock.ShowInterlocked(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
||||
});
|
||||
var indexOfNext = meetings.IndexOf(meeting) + 1;
|
||||
|
||||
// indexOf = 3, 4 meetings :
|
||||
if (indexOfNext < meetings.Count)
|
||||
TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText,
|
||||
meetings[indexOfNext].StartTime.ToShortTimeString());
|
||||
else
|
||||
TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, "No more meetings today");
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingModalClosePress, () =>
|
||||
{
|
||||
// Mark the meeting to not re-harass the user
|
||||
if (CurrentRoom.OnFeedback.BoolValue)
|
||||
LastMeetingDismissedId = meeting.Id;
|
||||
HideNextMeetingPopup();
|
||||
});
|
||||
|
||||
TriList.SetBool(UIBoolJoin.NextMeetingModalVisible, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void HideNextMeetingPopup()
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.NextMeetingModalVisible, false);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calendar should only be visible when it's supposed to
|
||||
/// </summary>
|
||||
public void CalendarPress()
|
||||
{
|
||||
//RefreshMeetingsList(); // List should be up-to-date
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dials a meeting after turning on room (if necessary)
|
||||
/// </summary>
|
||||
void RoomOnAndDialMeeting(Meeting meeting)
|
||||
{
|
||||
Action dialAction = () =>
|
||||
{
|
||||
var d = CurrentRoom.ScheduleSource as VideoCodecBase;
|
||||
if (d != null)
|
||||
{
|
||||
d.Dial(meeting);
|
||||
LastMeetingDismissedId = meeting.Id; // To prevent prompts for already-joined call
|
||||
}
|
||||
};
|
||||
if (CurrentRoom.OnFeedback.BoolValue)
|
||||
dialAction();
|
||||
else
|
||||
{
|
||||
// Rig a one-time handler to catch when the room is warmed and then dial call
|
||||
EventHandler<FeedbackEventArgs> oneTimeHandler = null;
|
||||
oneTimeHandler = (o, a) =>
|
||||
{
|
||||
if (!CurrentRoom.IsWarmingUpFeedback.BoolValue)
|
||||
{
|
||||
CurrentRoom.IsWarmingUpFeedback.OutputChange -= oneTimeHandler;
|
||||
dialAction();
|
||||
d.Dial(meeting);
|
||||
LastMeetingDismissedId = meeting.Id; // To prevent prompts for already-joined call
|
||||
}
|
||||
};
|
||||
CurrentRoom.IsWarmingUpFeedback.OutputChange += oneTimeHandler;
|
||||
ActivityCallButtonPressed();
|
||||
}
|
||||
}
|
||||
};
|
||||
if (CurrentRoom.OnFeedback.BoolValue)
|
||||
dialAction();
|
||||
else
|
||||
{
|
||||
// Rig a one-time handler to catch when the room is warmed and then dial call
|
||||
EventHandler<FeedbackEventArgs> oneTimeHandler = null;
|
||||
oneTimeHandler = (o, a) =>
|
||||
{
|
||||
if (!CurrentRoom.IsWarmingUpFeedback.BoolValue)
|
||||
{
|
||||
CurrentRoom.IsWarmingUpFeedback.OutputChange -= oneTimeHandler;
|
||||
dialAction();
|
||||
}
|
||||
};
|
||||
CurrentRoom.IsWarmingUpFeedback.OutputChange += oneTimeHandler;
|
||||
ActivityCallButtonPressed();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reveals the tech page and puts away anything that's in the way.
|
||||
@@ -592,11 +591,11 @@ namespace PepperDash.Essentials
|
||||
void SetupActivityFooterWhenRoomOn()
|
||||
{
|
||||
ActivityFooterSrl.Clear();
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl, 0,
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl, 0,
|
||||
b => { if (!b) ActivityShareButtonPressed(); }));
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl, 3,
|
||||
b => { if (!b) ActivityCallButtonPressed(); }));
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(3, ActivityFooterSrl, 4,
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(3, ActivityFooterSrl, 4,
|
||||
b => { if (!b) EndMeetingPress(); }));
|
||||
ActivityFooterSrl.Count = 3;
|
||||
TriList.SetUshort(UIUshortJoin.PresentationStagingCaretMode, 2); // center
|
||||
@@ -608,9 +607,9 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void SetActivityFooterFeedbacks()
|
||||
{
|
||||
CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call
|
||||
CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation
|
||||
ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None;
|
||||
}
|
||||
@@ -623,13 +622,13 @@ namespace PepperDash.Essentials
|
||||
if (VCDriver.IsVisible)
|
||||
return;
|
||||
HideLogo();
|
||||
HideNextMeetingPopup();
|
||||
HideNextMeetingPopup();
|
||||
TriList.SetBool(StartPageVisibleJoin, false);
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
if (CurrentSourcePageManager != null)
|
||||
CurrentSourcePageManager.Hide();
|
||||
PowerOnFromCall();
|
||||
PowerOnFromCall();
|
||||
CurrentMode = UiDisplayMode.Call;
|
||||
SetActivityFooterFeedbacks();
|
||||
VCDriver.Show();
|
||||
@@ -640,45 +639,45 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void ActivityShareButtonPressed()
|
||||
{
|
||||
SetupSourceList();
|
||||
SetupSourceList();
|
||||
if (VCDriver.IsVisible)
|
||||
VCDriver.Hide();
|
||||
HideNextMeetingPopup();
|
||||
HideNextMeetingPopup();
|
||||
TriList.SetBool(StartPageVisibleJoin, false);
|
||||
TriList.SetBool(UIBoolJoin.CallStagingBarVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, true);
|
||||
// Run default source when room is off and share is pressed
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
// If there's no default, show UI elements
|
||||
if (!CurrentRoom.RunDefaultPresentRoute())
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
}
|
||||
{
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
// If there's no default, show UI elements
|
||||
if (!CurrentRoom.RunDefaultPresentRoute())
|
||||
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)
|
||||
if(CurrentRoom.CurrentSourceInfo == null || CurrentRoom.CurrentSourceInfoKey == CurrentRoom.DefaultCodecRouteString)
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
else if (CurrentSourcePageManager != null)
|
||||
CurrentSourcePageManager.Show();
|
||||
}
|
||||
CurrentMode = UiDisplayMode.Presentation;
|
||||
SetupSourceList();
|
||||
SetupSourceList();
|
||||
SetActivityFooterFeedbacks();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Powers up the system to the codec route, if not already on.
|
||||
/// </summary>
|
||||
void PowerOnFromCall()
|
||||
{
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
CurrentRoom.RunDefaultCallRoute();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Powers up the system to the codec route, if not already on.
|
||||
/// </summary>
|
||||
void PowerOnFromCall()
|
||||
{
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
CurrentRoom.RunDefaultCallRoute();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows all sigs that are in CurrentDisplayModeSigsInUse
|
||||
@@ -705,22 +704,22 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void ShowCurrentSource()
|
||||
{
|
||||
if (CurrentRoom.CurrentSourceInfo == null)
|
||||
return;
|
||||
|
||||
if (CurrentRoom.CurrentSourceInfo.SourceDevice == null)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
return;
|
||||
}
|
||||
if (CurrentRoom.CurrentSourceInfo == null)
|
||||
return;
|
||||
|
||||
if (CurrentRoom.CurrentSourceInfo.SourceDevice == null)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
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.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
// Got an existing page manager, get it
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
// Got an existing page manager, get it
|
||||
if (PageManagers.ContainsKey(uiDev))
|
||||
pm = PageManagers[uiDev];
|
||||
// Otherwise make an apporiate one
|
||||
@@ -759,15 +758,15 @@ namespace PepperDash.Essentials
|
||||
CurrentRoom.StartShutdown(eShutdownType.Manual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Puts away modals and things that might be up when call comes in
|
||||
/// </summary>
|
||||
public void PrepareForCodecIncomingCall()
|
||||
{
|
||||
if (PowerDownModal != null && PowerDownModal.ModalIsVisible)
|
||||
PowerDownModal.CancelDialog();
|
||||
PopupInterlock.Hide();
|
||||
}
|
||||
/// <summary>
|
||||
/// Puts away modals and things that might be up when call comes in
|
||||
/// </summary>
|
||||
public void PrepareForCodecIncomingCall()
|
||||
{
|
||||
if (PowerDownModal != null && PowerDownModal.ModalIsVisible)
|
||||
PowerDownModal.CancelDialog();
|
||||
PopupInterlock.Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -912,7 +911,7 @@ namespace PepperDash.Essentials
|
||||
_CurrentRoom.OnFeedback.OutputChange -= CurrentRoom_OnFeedback_OutputChange;
|
||||
_CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
|
||||
_CurrentRoom.IsCoolingDownFeedback.OutputChange -= CurrentRoom_IsCoolingDownFeedback_OutputChange;
|
||||
_CurrentRoom.InCallFeedback.OutputChange -= CurrentRoom_InCallFeedback_OutputChange;
|
||||
_CurrentRoom.InCallFeedback.OutputChange -= CurrentRoom_InCallFeedback_OutputChange;
|
||||
}
|
||||
|
||||
_CurrentRoom = room;
|
||||
@@ -921,7 +920,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
// get the source list config and set up the source list
|
||||
|
||||
SetupSourceList();
|
||||
SetupSourceList();
|
||||
|
||||
// Name and logo
|
||||
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _CurrentRoom.Name;
|
||||
@@ -932,12 +931,12 @@ namespace PepperDash.Essentials
|
||||
_CurrentRoom.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished;
|
||||
_CurrentRoom.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled;
|
||||
|
||||
// Link up all the change events from the room
|
||||
// Link up all the change events from the room
|
||||
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
|
||||
CurrentRoom_SyncOnFeedback();
|
||||
_CurrentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange;
|
||||
_CurrentRoom.IsCoolingDownFeedback.OutputChange += CurrentRoom_IsCoolingDownFeedback_OutputChange;
|
||||
_CurrentRoom.InCallFeedback.OutputChange += CurrentRoom_InCallFeedback_OutputChange;
|
||||
_CurrentRoom.InCallFeedback.OutputChange += CurrentRoom_InCallFeedback_OutputChange;
|
||||
|
||||
|
||||
_CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
|
||||
@@ -975,7 +974,7 @@ namespace PepperDash.Essentials
|
||||
if (_CurrentRoom == room) return;
|
||||
// Disconnect current (probably never called)
|
||||
|
||||
if (_CurrentRoom != null)
|
||||
if(_CurrentRoom != null)
|
||||
_CurrentRoom.ConfigChanged -= room_ConfigChanged;
|
||||
|
||||
room.ConfigChanged -= room_ConfigChanged;
|
||||
@@ -1022,81 +1021,81 @@ namespace PepperDash.Essentials
|
||||
RefreshCurrentRoom(_CurrentRoom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void CurrentRoom_InCallFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
var inCall = CurrentRoom.InCallFeedback.BoolValue;
|
||||
if (inCall)
|
||||
{
|
||||
// Check if transitioning to in call - and non-sharable source is in use
|
||||
if (CurrentRoom.CurrentSourceInfo != null && CurrentRoom.CurrentSourceInfo.DisableCodecSharing)
|
||||
{
|
||||
Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source");
|
||||
CurrentRoom.RunRouteAction("codecOsd", CurrentRoom.SourceListKey);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void CurrentRoom_InCallFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
var inCall = CurrentRoom.InCallFeedback.BoolValue;
|
||||
if (inCall)
|
||||
{
|
||||
// Check if transitioning to in call - and non-sharable source is in use
|
||||
if (CurrentRoom.CurrentSourceInfo != null && CurrentRoom.CurrentSourceInfo.DisableCodecSharing)
|
||||
{
|
||||
Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source");
|
||||
CurrentRoom.RunRouteAction("codecOsd", CurrentRoom.SourceListKey);
|
||||
}
|
||||
}
|
||||
|
||||
SetupSourceList();
|
||||
}
|
||||
SetupSourceList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void SetupSourceList()
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void SetupSourceList()
|
||||
{
|
||||
|
||||
var inCall = CurrentRoom.InCallFeedback.BoolValue;
|
||||
var config = ConfigReader.ConfigObject.SourceLists;
|
||||
|
||||
|
||||
if (config.ContainsKey(_CurrentRoom.SourceListKey))
|
||||
{
|
||||
var srcList = config[_CurrentRoom.SourceListKey].OrderBy(kv => kv.Value.Order);
|
||||
|
||||
|
||||
var inCall = CurrentRoom.InCallFeedback.BoolValue;
|
||||
var config = ConfigReader.ConfigObject.SourceLists;
|
||||
// Setup sources list
|
||||
SourceStagingSrl.Clear();
|
||||
uint i = 1; // counter for UI list
|
||||
foreach (var kvp in srcList)
|
||||
{
|
||||
var srcConfig = kvp.Value;
|
||||
Debug.Console(1, "**** {0}, {1}, {2}, {3}, {4}", srcConfig.PreferredName, srcConfig.IncludeInSourceList,
|
||||
srcConfig.DisableCodecSharing, inCall, this.CurrentMode);
|
||||
// Skip sources marked as not included, and filter list of non-sharable sources when in call
|
||||
// or on share screen
|
||||
if (!srcConfig.IncludeInSourceList || (inCall && srcConfig.DisableCodecSharing)
|
||||
|| this.CurrentMode == UiDisplayMode.Call && srcConfig.DisableCodecSharing)
|
||||
{
|
||||
Debug.Console(1, "Skipping {0}", srcConfig.PreferredName);
|
||||
continue;
|
||||
}
|
||||
|
||||
var routeKey = kvp.Key;
|
||||
var item = new SubpageReferenceListSourceItem(i++, SourceStagingSrl, srcConfig,
|
||||
b => { if (!b) UiSelectSource(routeKey); });
|
||||
SourceStagingSrl.AddItem(item); // add to the SRL
|
||||
item.RegisterForSourceChange(_CurrentRoom);
|
||||
Debug.Console(1, "**** KEY {0}", kvp.Key);
|
||||
|
||||
}
|
||||
SourceStagingSrl.Count = (ushort)(i - 1);
|
||||
}
|
||||
|
||||
if (config.ContainsKey(_CurrentRoom.SourceListKey))
|
||||
{
|
||||
var srcList = config[_CurrentRoom.SourceListKey].OrderBy(kv => kv.Value.Order);
|
||||
}
|
||||
|
||||
|
||||
// Setup sources list
|
||||
SourceStagingSrl.Clear();
|
||||
uint i = 1; // counter for UI list
|
||||
foreach (var kvp in srcList)
|
||||
{
|
||||
var srcConfig = kvp.Value;
|
||||
Debug.Console(1, "**** {0}, {1}, {2}, {3}, {4}", srcConfig.PreferredName, srcConfig.IncludeInSourceList,
|
||||
srcConfig.DisableCodecSharing, inCall, this.CurrentMode);
|
||||
// Skip sources marked as not included, and filter list of non-sharable sources when in call
|
||||
// or on share screen
|
||||
if (!srcConfig.IncludeInSourceList || (inCall && srcConfig.DisableCodecSharing)
|
||||
|| this.CurrentMode == UiDisplayMode.Call && srcConfig.DisableCodecSharing)
|
||||
{
|
||||
Debug.Console(1, "Skipping {0}", srcConfig.PreferredName);
|
||||
continue;
|
||||
}
|
||||
|
||||
var routeKey = kvp.Key;
|
||||
var item = new SubpageReferenceListSourceItem(i++, SourceStagingSrl, srcConfig,
|
||||
b => { if (!b) UiSelectSource(routeKey); });
|
||||
SourceStagingSrl.AddItem(item); // add to the SRL
|
||||
item.RegisterForSourceChange(_CurrentRoom);
|
||||
Debug.Console(1, "**** KEY {0}", kvp.Key);
|
||||
|
||||
}
|
||||
SourceStagingSrl.Count = (ushort)(i - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the schedule changes, this event will fire
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void CodecSchedule_MeetingsListHasChanged(object sender, EventArgs e)
|
||||
{
|
||||
RefreshMeetingsList();
|
||||
}
|
||||
/// <summary>
|
||||
/// If the schedule changes, this event will fire
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void CodecSchedule_MeetingsListHasChanged(object sender, EventArgs e)
|
||||
{
|
||||
RefreshMeetingsList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the current shared source label on the call list when the source changes
|
||||
@@ -1129,51 +1128,51 @@ namespace PepperDash.Essentials
|
||||
|
||||
string callListSharedSourceLabel;
|
||||
|
||||
if (_CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _CurrentRoom.CurrentSourceInfo != null)
|
||||
{
|
||||
Debug.Console(0, "*#* CurrentRoom.CurrentSourceInfo = {0}",
|
||||
_CurrentRoom.CurrentSourceInfo != null ? _CurrentRoom.CurrentSourceInfo.SourceKey : "Nada!");
|
||||
callListSharedSourceLabel = _CurrentRoom.CurrentSourceInfo.PreferredName;
|
||||
}
|
||||
else
|
||||
callListSharedSourceLabel = "None";
|
||||
if (_CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _CurrentRoom.CurrentSourceInfo != null)
|
||||
{
|
||||
Debug.Console(0, "*#* CurrentRoom.CurrentSourceInfo = {0}",
|
||||
_CurrentRoom.CurrentSourceInfo != null ? _CurrentRoom.CurrentSourceInfo.SourceKey : "Nada!");
|
||||
callListSharedSourceLabel = _CurrentRoom.CurrentSourceInfo.PreferredName;
|
||||
}
|
||||
else
|
||||
callListSharedSourceLabel = "None";
|
||||
|
||||
TriList.StringInput[UIStringJoin.CallSharedSourceNameText].StringValue = callListSharedSourceLabel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void RefreshMeetingsList()
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void RefreshMeetingsList()
|
||||
{
|
||||
// See if this is helpful or if the callback response in the codec class maybe doesn't come it time?
|
||||
// Let's build list from event
|
||||
// CurrentRoom.ScheduleSource.GetSchedule();
|
||||
// CurrentRoom.ScheduleSource.GetSchedule();
|
||||
|
||||
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListIcon, "Calendar");
|
||||
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Today's Meetings");
|
||||
|
||||
ushort i = 0;
|
||||
foreach (var m in CurrentRoom.ScheduleSource.CodecSchedule.Meetings)
|
||||
{
|
||||
i++;
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 1).StringValue = m.StartTime.ToShortTimeString();
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 2).StringValue = m.EndTime.ToShortTimeString();
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 3).StringValue = m.Title;
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 4).StringValue = string.Format("<br>{0}", m.Organizer);
|
||||
ushort i = 0;
|
||||
foreach (var m in CurrentRoom.ScheduleSource.CodecSchedule.Meetings)
|
||||
{
|
||||
i++;
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 1).StringValue = m.StartTime.ToShortTimeString();
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 2).StringValue = m.EndTime.ToShortTimeString();
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 3).StringValue = m.Title;
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 4).StringValue = string.Format("<br>{0}",m.Organizer);
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 5).StringValue = "Join";
|
||||
MeetingOrContactMethodModalSrl.BoolInputSig(i, 2).BoolValue = m.Joinable;
|
||||
var mm = m; // lambda scope
|
||||
MeetingOrContactMethodModalSrl.GetBoolFeedbackSig(i, 1).SetSigFalseAction(() =>
|
||||
{
|
||||
PopupInterlock.Hide();
|
||||
ActivityCallButtonPressed();
|
||||
var d = CurrentRoom.ScheduleSource as VideoCodecBase;
|
||||
if (d != null)
|
||||
RoomOnAndDialMeeting(mm);
|
||||
});
|
||||
}
|
||||
MeetingOrContactMethodModalSrl.Count = i;
|
||||
MeetingOrContactMethodModalSrl.BoolInputSig(i, 2).BoolValue = m.Joinable;
|
||||
var mm = m; // lambda scope
|
||||
MeetingOrContactMethodModalSrl.GetBoolFeedbackSig(i, 1).SetSigFalseAction(() =>
|
||||
{
|
||||
PopupInterlock.Hide();
|
||||
ActivityCallButtonPressed();
|
||||
var d = CurrentRoom.ScheduleSource as VideoCodecBase;
|
||||
if (d != null)
|
||||
RoomOnAndDialMeeting(mm);
|
||||
});
|
||||
}
|
||||
MeetingOrContactMethodModalSrl.Count = i;
|
||||
|
||||
if (i == 0) // Show item indicating no meetings are booked for rest of day
|
||||
{
|
||||
@@ -1185,12 +1184,12 @@ namespace PepperDash.Essentials
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(1, 4).StringValue = string.Empty;
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(1, 5).StringValue = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For room on/off changes
|
||||
/// </summary>
|
||||
void CurrentRoom_OnFeedback_OutputChange(object sender, EventArgs e)
|
||||
/// <summary>
|
||||
/// For room on/off changes
|
||||
/// </summary>
|
||||
void CurrentRoom_OnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
CurrentRoom_SyncOnFeedback();
|
||||
}
|
||||
@@ -1222,8 +1221,8 @@ namespace PepperDash.Essentials
|
||||
SetActivityFooterFeedbacks();
|
||||
TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
// Clear this so that the pesky meeting warning can resurface every minute when off
|
||||
LastMeetingDismissedId = null;
|
||||
// Clear this so that the pesky meeting warning can resurface every minute when off
|
||||
LastMeetingDismissedId = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1234,11 +1233,11 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
if (CurrentRoom.IsWarmingUpFeedback.BoolValue)
|
||||
{
|
||||
ShowNotificationRibbon("Room is powering on. Please wait...", 0);
|
||||
ShowNotificationRibbon("Room is powering on. Please wait...", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowNotificationRibbon("Room is powered on. Welcome.", 2000);
|
||||
ShowNotificationRibbon("Room is powered on. Welcome.", 2000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1251,11 +1250,11 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
if (CurrentRoom.IsCoolingDownFeedback.BoolValue)
|
||||
{
|
||||
ShowNotificationRibbon("Room is powering off. Please wait.", 0);
|
||||
ShowNotificationRibbon("Room is powering off. Please wait.", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
HideNotificationRibbon();
|
||||
HideNotificationRibbon();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,14 +10,11 @@ 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.Core.Devices.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Core.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
|
||||
namespace PepperDash.Essentials.UIDrivers.VC
|
||||
{
|
||||
|
||||
@@ -99,12 +99,19 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
Eisc.SigChange += Eisc_SigChange;
|
||||
|
||||
AddPostActivationAction(LinkDevices);
|
||||
AddPostActivationAction(LinkRooms);
|
||||
}
|
||||
|
||||
private void LinkDevices()
|
||||
{
|
||||
Debug.Console(1, this, "Linking Devices...");
|
||||
|
||||
if (PropertiesConfig.Devices == null)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "No devices linked to this bridge");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var d in PropertiesConfig.Devices)
|
||||
{
|
||||
var device = DeviceManager.GetDeviceForKey(d.DeviceKey);
|
||||
@@ -131,6 +138,16 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
}
|
||||
}
|
||||
|
||||
RegisterEisc();
|
||||
}
|
||||
|
||||
private void RegisterEisc()
|
||||
{
|
||||
if (Eisc.Registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var registerResult = Eisc.Register();
|
||||
|
||||
if (registerResult != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
@@ -142,6 +159,33 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "EISC registration successful");
|
||||
}
|
||||
|
||||
public void LinkRooms()
|
||||
{
|
||||
Debug.Console(1, this, "Linking Rooms...");
|
||||
|
||||
if (PropertiesConfig.Rooms == null)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "No rooms linked to this bridge.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var room in PropertiesConfig.Rooms)
|
||||
{
|
||||
var rm = DeviceManager.GetDeviceForKey(room.RoomKey) as IBridgeAdvanced;
|
||||
|
||||
if (rm == null)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice,
|
||||
"Room {0} does not implement IBridgeAdvanced. Skipping...", room.RoomKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
rm.LinkToApi(Eisc, room.JoinStart, room.JoinMapKey, this);
|
||||
}
|
||||
|
||||
RegisterEisc();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a join map
|
||||
/// </summary>
|
||||
@@ -290,6 +334,9 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
[JsonProperty("devices")]
|
||||
public List<ApiDevicePropertiesConfig> Devices { get; set; }
|
||||
|
||||
[JsonProperty("rooms")]
|
||||
public List<ApiRoomPropertiesConfig> Rooms { get; set; }
|
||||
|
||||
|
||||
public class ApiDevicePropertiesConfig
|
||||
{
|
||||
@@ -303,6 +350,18 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
public string JoinMapKey { get; set; }
|
||||
}
|
||||
|
||||
public class ApiRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
[JsonProperty("joinStart")]
|
||||
public uint JoinStart { get; set; }
|
||||
|
||||
[JsonProperty("joinMapKey")]
|
||||
public string JoinMapKey { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class EiscApiAdvancedFactory : EssentialsDeviceFactory<EiscApiAdvanced>
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
/// <param name="type">Type of the child join map</param>
|
||||
public AppleTvJoinMap(uint joinStart, Type type) : base(joinStart, type)
|
||||
{
|
||||
}
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,14 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
public JoinDataComplete HdcpSupportCapability = new JoinDataComplete(new JoinData { JoinNumber = 1201, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Input HDCP Support Capability", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("InputStreamCardState")]
|
||||
public JoinDataComplete InputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1501, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("OutputStreamCardState")]
|
||||
public JoinDataComplete OutputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1601, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("InputNames")]
|
||||
public JoinDataComplete InputNames = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
||||
namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
{
|
||||
public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
||||
namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
{
|
||||
public class VideoCodecControllerJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
|
||||
@@ -56,6 +56,11 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
private void RegisterAndConfigureComPort()
|
||||
{
|
||||
if (Port == null)
|
||||
{
|
||||
Debug.Console(0,this,Debug.ErrorLogLevel.Error, "Configured com Port for this device does not exist.");
|
||||
return;
|
||||
}
|
||||
if (Port.Parent is CrestronControlSystem)
|
||||
{
|
||||
var result = Port.Register();
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace PepperDash.Essentials.Core
|
||||
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
|
||||
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
|
||||
return dev.ComPorts[config.ControlPortNumber];
|
||||
Debug.Console(0, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
||||
Debug.Console(0,Debug.ErrorLogLevel.Notice, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
@@ -24,10 +23,7 @@ namespace PepperDash.Essentials.Core.Config
|
||||
[JsonProperty("sourceLists")]
|
||||
public Dictionary<string, Dictionary<string, SourceListItem>> SourceLists { get; set; }
|
||||
|
||||
[JsonProperty("destinationLists")]
|
||||
public Dictionary<string, Dictionary<string, DestinationListItem>> DestinationLists { get; set; }
|
||||
|
||||
[JsonProperty("tieLines")]
|
||||
[JsonProperty("tieLines")]
|
||||
public List<TieLineConfig> TieLines { get; set; }
|
||||
|
||||
[JsonProperty("joinMaps")]
|
||||
@@ -44,14 +40,6 @@ namespace PepperDash.Essentials.Core.Config
|
||||
return SourceLists[key];
|
||||
}
|
||||
|
||||
public Dictionary<string, DestinationListItem> GetDestinationListForKey(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key) || !SourceLists.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
|
||||
/// </summary>
|
||||
@@ -64,9 +52,12 @@ namespace PepperDash.Essentials.Core.Config
|
||||
|
||||
var deviceConfig = Devices.FirstOrDefault(d => d.Key.Equals(key));
|
||||
|
||||
//removed if statement that was here...
|
||||
//DeviceConfig will be null if it's not found in the list
|
||||
return deviceConfig;
|
||||
if (deviceConfig != null)
|
||||
return deviceConfig;
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
public interface IHasExternalSourceSwitching
|
||||
{
|
||||
bool ExternalSourceListEnabled { get; }
|
||||
string ExternalSourceInputPort { get; }
|
||||
void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type);
|
||||
void SetExternalSourceState(string key, eExternalSourceMode mode);
|
||||
void ClearExternalSources();
|
||||
void SetSelectedSource(string key);
|
||||
Action<string, string> RunRouteAction { set;}
|
||||
}
|
||||
|
||||
public enum eExternalSourceType { camera, desktop, document_camera, mediaplayer, PC, whiteboard, other }
|
||||
public enum eExternalSourceMode { Ready, NotReady, Hidden, Error }
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
||||
{
|
||||
public interface IHasParticipants
|
||||
{
|
||||
CodecParticipants Participants { get; }
|
||||
}
|
||||
|
||||
public interface IHasParticipantVideoMute:IHasParticipants
|
||||
{
|
||||
void MuteVideoForParticipant(int userId);
|
||||
void UnmuteVideoForParticipant(int userId);
|
||||
void ToggleVideoForParticipant(int userId);
|
||||
}
|
||||
|
||||
public interface IHasParticipantAudioMute:IHasParticipantVideoMute
|
||||
{
|
||||
void MuteAudioForParticipant(int userId);
|
||||
void UnmuteAudioForParticipant(int userId);
|
||||
void ToggleAudioForParticipant(int userId);
|
||||
}
|
||||
|
||||
public class CodecParticipants
|
||||
{
|
||||
private List<Participant> _currentParticipants;
|
||||
|
||||
public List<Participant> CurrentParticipants {
|
||||
get { return _currentParticipants; }
|
||||
set
|
||||
{
|
||||
_currentParticipants = value;
|
||||
var handler = ParticipantsListHasChanged;
|
||||
|
||||
if(handler == null) return;
|
||||
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> ParticipantsListHasChanged;
|
||||
|
||||
public CodecParticipants()
|
||||
{
|
||||
_currentParticipants = new List<Participant>();
|
||||
}
|
||||
}
|
||||
|
||||
public class Participant
|
||||
{
|
||||
public bool IsHost { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool CanMuteVideo { get; set; }
|
||||
public bool CanUnmuteVideo { get; set; }
|
||||
public bool VideoMuteFb { get; set; }
|
||||
public bool AudioMuteFb { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasSelfviewPosition
|
||||
{
|
||||
StringFeedback SelfviewPipPositionFeedback { get; }
|
||||
|
||||
void SelfviewPipPositionSet(CodecCommandWithLabel position);
|
||||
|
||||
void SelfviewPipPositionToggle();
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace PepperDash.Essentials.Core.Devices.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines minimum volume controls for a codec device with dialing capabilities
|
||||
/// </summary>
|
||||
public interface ICodecAudio : IBasicVolumeWithFeedback, IPrivacy
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
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};
|
||||
}
|
||||
|
||||
public void UpdateRecentCallsList(List<CallHistoryEntry> entries)
|
||||
{
|
||||
RecentCalls = entries;
|
||||
|
||||
OnRecentCallsListChange();
|
||||
}
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Devices.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.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>
|
||||
[Obsolete("Please use the Stack-based history instead")]
|
||||
List<CodecDirectory> DirectoryBrowseHistory { get; }
|
||||
}
|
||||
|
||||
public interface IHasDirectoryHistoryStack : IHasDirectory
|
||||
{
|
||||
Stack<CodecDirectory> DirectoryBrowseHistoryStack { 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; }
|
||||
|
||||
[JsonProperty("parentFolderId")]
|
||||
public string ParentFolderId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a folder type DirectoryItem
|
||||
/// </summary>
|
||||
public class DirectoryFolder : DirectoryItem
|
||||
{
|
||||
[JsonProperty("contacts")]
|
||||
public List<DirectoryContact> Contacts { 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
|
||||
}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
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;
|
||||
|
||||
private int _meetingWarningMinutes = 5;
|
||||
|
||||
public int MeetingWarningMinutes
|
||||
{
|
||||
get { return _meetingWarningMinutes; }
|
||||
set { _meetingWarningMinutes = value; }
|
||||
}
|
||||
|
||||
/// <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);
|
||||
}
|
||||
|
||||
public CodecScheduleAwareness(long pollTime)
|
||||
{
|
||||
Meetings = new List<Meeting>();
|
||||
|
||||
_scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime);
|
||||
}
|
||||
|
||||
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 (var m in Meetings)
|
||||
{
|
||||
var 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 int MinutesBeforeMeeting;
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Organizer { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Agenda { get; set; }
|
||||
|
||||
public TimeSpan MeetingWarningMinutes
|
||||
{
|
||||
get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); }
|
||||
}
|
||||
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(-MinutesBeforeMeeting) <= 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; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasBranding
|
||||
{
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasPhoneDialing
|
||||
{
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
|
||||
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; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface ILanguageDefinition
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface ILanguageProvider
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface INumericKeypad
|
||||
public interface INumericKeypad:IKeyed
|
||||
{
|
||||
void Digit0(bool pressRelease);
|
||||
void Digit1(bool pressRelease);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface ITvPresetsProvider
|
||||
{
|
||||
DevicePresetsModel TvPresets { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
public class LanguageLabel
|
||||
{
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
||||
namespace PepperDash.Essentials.Core.Devices
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a codec command that might need to have a friendly label applied for UI feedback purposes
|
||||
/// </summary>
|
||||
public class CodecCommandWithLabel
|
||||
{
|
||||
public string Command { get; set; }
|
||||
public string Label { get; set; }
|
||||
|
||||
public CodecCommandWithLabel(string command, string label)
|
||||
{
|
||||
Command = command;
|
||||
Label = label;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -7,7 +7,7 @@ using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices
|
||||
namespace PepperDash_Essentials_Core.Devices
|
||||
{
|
||||
public class GenericIrController: EssentialsBridgeableDevice
|
||||
{
|
||||
|
||||
@@ -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,22 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes a camera with preset functionality
|
||||
/// </summary>
|
||||
public interface IHasCameraPresets
|
||||
{
|
||||
event EventHandler<EventArgs> PresetsListHasChanged;
|
||||
|
||||
List<CameraPreset> Presets { get; }
|
||||
|
||||
void PresetSelect(int preset);
|
||||
|
||||
void PresetStore(int preset, string description);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
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.Presets;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for camera presets
|
||||
/// </summary>
|
||||
public interface IHasCodecRoomPresets
|
||||
{
|
||||
event EventHandler<EventArgs> CodecRoomPresetsListHasChanged;
|
||||
|
||||
List<CodecRoomPreset> NearEndPresets { get; }
|
||||
|
||||
List<CodecRoomPreset> FarEndRoomPresets { get; }
|
||||
|
||||
void CodecRoomPresetSelect(int preset);
|
||||
|
||||
void CodecRoomPresetStore(int preset, string description);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a room preset on a video codec. Typically stores camera position(s) and video routing. Can be recalled by Far End if enabled.
|
||||
/// </summary>
|
||||
public class CodecRoomPreset : PresetBase
|
||||
{
|
||||
public CodecRoomPreset(int id, string description, bool def, bool isDef)
|
||||
: base(id, description, def, isDef)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
@@ -24,11 +31,16 @@ namespace PepperDash.Essentials.Core
|
||||
/// Returns the source Device for this, if it exists in DeviceManager
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public EssentialsDevice SourceDevice
|
||||
public Device SourceDevice
|
||||
{
|
||||
get { return _sourceDevice ?? (_sourceDevice = DeviceManager.GetDeviceForKey(SourceKey) as EssentialsDevice); }
|
||||
get
|
||||
{
|
||||
if (_SourceDevice == null)
|
||||
_SourceDevice = DeviceManager.GetDeviceForKey(SourceKey) as Device;
|
||||
return _SourceDevice;
|
||||
}
|
||||
}
|
||||
private EssentialsDevice _sourceDevice;
|
||||
Device _SourceDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the source's Name or this AlternateName property, if
|
||||
@@ -39,12 +51,13 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
return SourceDevice == null ? "---" : SourceDevice.Name;
|
||||
if (string.IsNullOrEmpty(Name))
|
||||
{
|
||||
if (SourceDevice == null)
|
||||
return "---";
|
||||
return SourceDevice.Name;
|
||||
}
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace PepperDash.Essentials.Core
|
||||
public IrOutputPortController IrPort { get; private set; }
|
||||
public ushort IrPulseTime { get; set; }
|
||||
|
||||
public BoolFeedback PowerIsOnFeedback { get; private set; }
|
||||
[Obsolete("This property will be removed in version 2.0.0")]
|
||||
public override BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
protected Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking
|
||||
public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IPower
|
||||
{
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
@@ -49,6 +49,9 @@ namespace PepperDash.Essentials.Core
|
||||
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
|
||||
[Obsolete("This property will be removed in version 2.0.0")]
|
||||
public abstract BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
public uint WarmupTime { get; set; }
|
||||
@@ -81,8 +84,6 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public abstract void PowerOn();
|
||||
public abstract void PowerOff();
|
||||
public abstract void PowerToggle();
|
||||
@@ -99,7 +100,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ExecuteSwitch(object selector);
|
||||
public abstract void ExecuteSwitch(object selector);
|
||||
|
||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||
EiscApiAdvanced bridge)
|
||||
@@ -261,7 +262,8 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||
|
||||
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
public override BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||
|
||||
|
||||
@@ -315,7 +317,5 @@ namespace PepperDash.Essentials.Core
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
namespace PepperDash_Essentials_Core
|
||||
{
|
||||
public class IsReadyEventArgs : EventArgs
|
||||
{
|
||||
|
||||
@@ -1,218 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharpPro;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
public class EssentialsDualDisplayFusionController:EssentialsHuddleSpaceFusionSystemControllerBase
|
||||
{
|
||||
private BooleanSigData _codecIsInCall;
|
||||
private readonly EssentialsDualDisplayRoom _room;
|
||||
|
||||
public EssentialsDualDisplayFusionController(EssentialsDualDisplayRoom room, uint ipId) : base(room, ipId)
|
||||
{
|
||||
_room = room;
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsHuddleSpaceFusionSystemControllerBase
|
||||
|
||||
protected override void ExecuteCustomSteps()
|
||||
{
|
||||
var leftDisplay = _room.LeftDisplay as DisplayBase;
|
||||
var rightDisplay = _room.RightDisplay as DisplayBase;
|
||||
|
||||
SetUpCodec();
|
||||
SetUpDisplay(leftDisplay);
|
||||
SetUpDisplay(rightDisplay);
|
||||
base.ExecuteCustomSteps();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides of EssentialsHuddleSpaceFusionSystemControllerBase
|
||||
|
||||
protected override void SetUpDisplay()
|
||||
{
|
||||
Debug.Console(1, this, "No default Display fo this room");
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Creates a static asset for the codec and maps the joins to the main room symbol
|
||||
/// </summary>
|
||||
private void SetUpCodec()
|
||||
{
|
||||
try
|
||||
{
|
||||
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
|
||||
if (essentialsHuddleVtc1Room == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var codec = essentialsHuddleVtc1Room.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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,29 +11,35 @@ using Crestron.SimplSharpPro.Fusion;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Rooms;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
public class EssentialsHuddleSpaceFusionSystemControllerBase : EssentialsDevice, IOccupancyStatusProvider
|
||||
public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider
|
||||
{
|
||||
protected EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap;
|
||||
|
||||
private const string RemoteOccupancyXml = "<Occupancy><Type>Local</Type><State>{0}</State></Occupancy>";
|
||||
private readonly bool _guidFileExists;
|
||||
|
||||
private readonly Dictionary<Device, BoolInputSig> _sourceToFeedbackSigs =
|
||||
new Dictionary<Device, BoolInputSig>();
|
||||
|
||||
private Event _currentMeeting;
|
||||
|
||||
protected StringSigData CurrentRoomSourceNameSig;
|
||||
|
||||
private RoomSchedule _currentSchedule;
|
||||
public FusionCustomPropertiesBridge CustomPropertiesBridge = new FusionCustomPropertiesBridge();
|
||||
private CTimer _dailyTimeRequestTimer;
|
||||
protected FusionOccupancySensorAsset FusionOccSensor;
|
||||
protected FusionRemoteOccupancySensor FusionRemoteOccSensor;
|
||||
|
||||
protected FusionRoom FusionRoom;
|
||||
protected Dictionary<int, FusionAsset> FusionStaticAssets;
|
||||
public long PushNotificationTimeout = 5000;
|
||||
protected EssentialsRoomBase Room;
|
||||
public long SchedulePollInterval = 300000;
|
||||
|
||||
private Event _currentMeeting;
|
||||
private RoomSchedule _currentSchedule;
|
||||
private CTimer _dailyTimeRequestTimer;
|
||||
private StatusMonitorCollection _errorMessageRollUp;
|
||||
|
||||
private FusionRoomGuids _guiDs;
|
||||
private uint _ipId;
|
||||
@@ -42,14 +48,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
private Event _nextMeeting;
|
||||
|
||||
private CTimer _pollTimer;
|
||||
public long PushNotificationTimeout = 5000;
|
||||
|
||||
private CTimer _pushNotificationTimer;
|
||||
protected EssentialsRoomBase Room;
|
||||
|
||||
// Default poll time is 5 min unless overridden by config value
|
||||
public long SchedulePollInterval = 300000;
|
||||
private StatusMonitorCollection _errorMessageRollUp;
|
||||
|
||||
private string _roomOccupancyRemoteString;
|
||||
|
||||
@@ -86,11 +86,21 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
#endregion
|
||||
|
||||
public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId)
|
||||
public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId, string joinMapKey)
|
||||
: base(room.Key + "-fusion")
|
||||
{
|
||||
try
|
||||
{
|
||||
JoinMap = new EssentialsHuddleSpaceRoomFusionRoomJoinMap(1);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand((o) => JoinMap.PrintJoinMapInfo(), string.Format("ptjnmp-{0}", Key), "Prints Attribute Join Map", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapKey))
|
||||
{
|
||||
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
|
||||
JoinMap.SetCustomJoinData(customJoins);
|
||||
}
|
||||
|
||||
Room = room;
|
||||
|
||||
_ipId = ipId;
|
||||
@@ -106,7 +116,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
var slot = Global.ControlSystem.ProgramNumber;
|
||||
|
||||
var guidFilePath = Global.FilePathPrefix +
|
||||
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
||||
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
||||
|
||||
_guidFileExists = File.Exists(guidFilePath);
|
||||
|
||||
@@ -123,8 +133,6 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
ReadGuidFile(guidFilePath);
|
||||
}
|
||||
|
||||
Initialize();
|
||||
|
||||
if (Room.RoomOccupancy != null)
|
||||
{
|
||||
if (Room.OccupancyStatusProviderIsRemote)
|
||||
@@ -137,10 +145,20 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
}
|
||||
|
||||
// Make it so!
|
||||
FusionRVI.GenerateFileForAllFusionDevices();
|
||||
|
||||
GenerateGuidFile(guidFilePath);
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
CreateSymbolAndBasicSigs(_ipId);
|
||||
SetUpSources();
|
||||
SetUpCommunitcationMonitors();
|
||||
SetUpDisplay();
|
||||
SetUpError();
|
||||
ExecuteCustomSteps();
|
||||
|
||||
FusionRVI.GenerateFileForAllFusionDevices();
|
||||
|
||||
GenerateGuidFile(guidFilePath);
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -181,16 +199,6 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
}
|
||||
|
||||
protected void Initialize()
|
||||
{
|
||||
CreateSymbolAndBasicSigs(_ipId);
|
||||
SetUpSources();
|
||||
SetUpCommunitcationMonitors();
|
||||
SetUpDisplay();
|
||||
SetUpError();
|
||||
ExecuteCustomSteps();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the guid file in NVRAM. If the file already exists it will be overwritten.
|
||||
/// </summary>
|
||||
@@ -280,7 +288,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Fusion Guids successfully read from file: {0}",
|
||||
filePath);
|
||||
|
||||
Debug.Console(1, this, "\nRoom Name: {0}\nIPID: {1:x}\n RoomGuid: {2}", Room.Name, _ipId, RoomGuid);
|
||||
Debug.Console(1, this, "\r\n********************\r\n\tRoom Name: {0}\r\n\tIPID: {1:X}\r\n\tRoomGuid: {2}\r\n*******************", Room.Name, _ipId, RoomGuid);
|
||||
|
||||
foreach (var item in FusionStaticAssets)
|
||||
{
|
||||
@@ -331,28 +339,25 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
|
||||
|
||||
// Moved to
|
||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source",
|
||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.Metadata.Description,
|
||||
eSigIoMask.InputSigOnly);
|
||||
// Don't think we need to get current status of this as nothing should be alive yet.
|
||||
var hasCurrentSourceInfoChange = Room as IHasCurrentSourceInfoChange;
|
||||
if (hasCurrentSourceInfoChange != null)
|
||||
{
|
||||
hasCurrentSourceInfoChange.CurrentSourceChange +=
|
||||
Room_CurrentSourceInfoChange;
|
||||
hasCurrentSourceInfoChange.CurrentSourceChange += Room_CurrentSourceInfoChange;
|
||||
}
|
||||
|
||||
|
||||
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(
|
||||
Room.PowerOnToDefaultOrLastSource);
|
||||
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(
|
||||
() =>
|
||||
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(Room.PowerOnToDefaultOrLastSource);
|
||||
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() =>
|
||||
{
|
||||
var runRouteAction = Room as IRunRouteAction;
|
||||
if (runRouteAction != null)
|
||||
{
|
||||
var runRouteAction = Room as IRunRouteAction;
|
||||
if (runRouteAction != null)
|
||||
{
|
||||
runRouteAction.RunRouteAction("roomOff", Room.SourceListKey);
|
||||
}
|
||||
});
|
||||
runRouteAction.RunRouteAction("roomOff", Room.SourceListKey);
|
||||
}
|
||||
});
|
||||
// NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
|
||||
FusionRoom.ErrorMessage.InputSig.StringValue =
|
||||
"3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;";
|
||||
@@ -365,8 +370,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
GetProcessorInfo();
|
||||
|
||||
CrestronEnvironment.EthernetEventHandler +=
|
||||
CrestronEnvironment_EthernetEventHandler;
|
||||
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
||||
}
|
||||
|
||||
protected void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs)
|
||||
@@ -385,24 +389,24 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
var response = string.Empty;
|
||||
|
||||
var systemReboot = FusionRoom.CreateOffsetBoolSig(74, "Processor - Reboot", eSigIoMask.OutputSigOnly);
|
||||
var systemReboot = FusionRoom.CreateOffsetBoolSig(JoinMap.ProcessorReboot.JoinNumber, JoinMap.ProcessorReboot.Metadata.Description, eSigIoMask.OutputSigOnly);
|
||||
systemReboot.OutputSig.SetSigFalseAction(
|
||||
() => CrestronConsole.SendControlSystemCommand("reboot", ref response));
|
||||
}
|
||||
|
||||
protected void SetUpEthernetValues()
|
||||
{
|
||||
_ip1 = FusionRoom.CreateOffsetStringSig(50, "Info - Processor - IP 1", eSigIoMask.InputSigOnly);
|
||||
_ip2 = FusionRoom.CreateOffsetStringSig(51, "Info - Processor - IP 2", eSigIoMask.InputSigOnly);
|
||||
_gateway = FusionRoom.CreateOffsetStringSig(52, "Info - Processor - Gateway", eSigIoMask.InputSigOnly);
|
||||
_hostname = FusionRoom.CreateOffsetStringSig(53, "Info - Processor - Hostname", eSigIoMask.InputSigOnly);
|
||||
_domain = FusionRoom.CreateOffsetStringSig(54, "Info - Processor - Domain", eSigIoMask.InputSigOnly);
|
||||
_dns1 = FusionRoom.CreateOffsetStringSig(55, "Info - Processor - DNS 1", eSigIoMask.InputSigOnly);
|
||||
_dns2 = FusionRoom.CreateOffsetStringSig(56, "Info - Processor - DNS 2", eSigIoMask.InputSigOnly);
|
||||
_mac1 = FusionRoom.CreateOffsetStringSig(57, "Info - Processor - MAC 1", eSigIoMask.InputSigOnly);
|
||||
_mac2 = FusionRoom.CreateOffsetStringSig(58, "Info - Processor - MAC 2", eSigIoMask.InputSigOnly);
|
||||
_netMask1 = FusionRoom.CreateOffsetStringSig(59, "Info - Processor - Net Mask 1", eSigIoMask.InputSigOnly);
|
||||
_netMask2 = FusionRoom.CreateOffsetStringSig(60, "Info - Processor - Net Mask 2", eSigIoMask.InputSigOnly);
|
||||
_ip1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp1.JoinNumber, JoinMap.ProcessorIp1.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
_ip2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp2.JoinNumber, JoinMap.ProcessorIp2.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
_gateway = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorGateway.JoinNumber, JoinMap.ProcessorGateway.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
_hostname = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorHostname.JoinNumber, JoinMap.ProcessorHostname.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
_domain = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDomain.JoinNumber, JoinMap.ProcessorDomain.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
_dns1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns1.JoinNumber, JoinMap.ProcessorDns1.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
_dns2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns2.JoinNumber, JoinMap.ProcessorDns2.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
_mac1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac1.JoinNumber, JoinMap.ProcessorMac1.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
_mac2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac2.JoinNumber, JoinMap.ProcessorMac2.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
_netMask1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask1.JoinNumber, JoinMap.ProcessorNetMask1.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
_netMask2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask2.JoinNumber, JoinMap.ProcessorNetMask2.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
}
|
||||
|
||||
protected void GetProcessorEthernetValues()
|
||||
@@ -455,16 +459,16 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
protected void GetProcessorInfo()
|
||||
{
|
||||
_firmware = FusionRoom.CreateOffsetStringSig(61, "Info - Processor - Firmware", eSigIoMask.InputSigOnly);
|
||||
_firmware = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorFirmware.JoinNumber, JoinMap.ProcessorFirmware.Metadata.Description, eSigIoMask.InputSigOnly);
|
||||
|
||||
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server)
|
||||
{
|
||||
for (var i = 0; i < Global.ControlSystem.NumProgramsSupported; i++)
|
||||
{
|
||||
var join = 62 + i;
|
||||
var join = JoinMap.ProgramNameStart.JoinNumber + i;
|
||||
var progNum = i + 1;
|
||||
_program[i] = FusionRoom.CreateOffsetStringSig((uint) join,
|
||||
string.Format("Info - Processor - Program {0}", progNum), eSigIoMask.InputSigOnly);
|
||||
string.Format("{0} {1}", JoinMap.ProgramNameStart.Metadata.Description, progNum), eSigIoMask.InputSigOnly);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +479,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
if (FusionRoom.IsOnline)
|
||||
{
|
||||
const string fusionRoomCustomPropertiesRequest = @"<RequestRoomConfiguration><RequestID>RoomConfigurationRequest</RequestID><CustomProperties><Property></Property></CustomProperties></RequestRoomConfiguration>";
|
||||
const string fusionRoomCustomPropertiesRequest =
|
||||
@"<RequestRoomConfiguration><RequestID>RoomConfigurationRequest</RequestID><CustomProperties><Property></Property></CustomProperties></RequestRoomConfiguration>";
|
||||
|
||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.RoomConfigQuery.StringValue =
|
||||
fusionRoomCustomPropertiesRequest;
|
||||
@@ -491,57 +496,60 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
if (args.DeviceOnLine)
|
||||
{
|
||||
CrestronEnvironment.Sleep(200);
|
||||
|
||||
// Send Push Notification Action request:
|
||||
|
||||
const string requestId = "InitialPushRequest";
|
||||
|
||||
|
||||
var actionRequest =
|
||||
string.Format("<RequestAction>\n<RequestID>{0}</RequestID>\n", requestId) +
|
||||
"<ActionID>RegisterPushModel</ActionID>\n" +
|
||||
"<Parameters>\n" +
|
||||
"<Parameter ID='Enabled' Value='1' />\n" +
|
||||
"<Parameter ID='RequestID' Value='PushNotification' />\n" +
|
||||
"<Parameter ID='Start' Value='00:00:00' />\n" +
|
||||
"<Parameter ID='HourSpan' Value='24' />\n" +
|
||||
"<Parameter ID='Field' Value='MeetingID' />\n" +
|
||||
"<Parameter ID='Field' Value='RVMeetingID' />\n" +
|
||||
"<Parameter ID='Field' Value='InstanceID' />\n" +
|
||||
"<Parameter ID='Field' Value='dtStart' />\n" +
|
||||
"<Parameter ID='Field' Value='dtEnd' />\n" +
|
||||
"<Parameter ID='Field' Value='Subject' />\n" +
|
||||
"<Parameter ID='Field' Value='Organizer' />\n" +
|
||||
"<Parameter ID='Field' Value='IsEvent' />\n" +
|
||||
"<Parameter ID='Field' Value='IsPrivate' />\n" +
|
||||
"<Parameter ID='Field' Value='IsExchangePrivate' />\n" +
|
||||
"<Parameter ID='Field' Value='LiveMeeting' />\n" +
|
||||
"<Parameter ID='Field' Value='ShareDocPath' />\n" +
|
||||
"<Parameter ID='Field' Value='PhoneNo' />\n" +
|
||||
"<Parameter ID='Field' Value='ParticipantCode' />\n" +
|
||||
"</Parameters>\n" +
|
||||
"</RequestAction>\n";
|
||||
|
||||
Debug.Console(2, this, "Sending Fusion ActionRequest: \n{0}", actionRequest);
|
||||
|
||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.ActionQuery.StringValue = actionRequest;
|
||||
|
||||
GetCustomProperties();
|
||||
|
||||
// Request current Fusion Server Time
|
||||
RequestLocalDateTime(null);
|
||||
|
||||
// Setup timer to request time daily
|
||||
if (_dailyTimeRequestTimer != null && !_dailyTimeRequestTimer.Disposed)
|
||||
CrestronInvoke.BeginInvoke( (o) =>
|
||||
{
|
||||
_dailyTimeRequestTimer.Stop();
|
||||
_dailyTimeRequestTimer.Dispose();
|
||||
}
|
||||
CrestronEnvironment.Sleep(200);
|
||||
|
||||
_dailyTimeRequestTimer = new CTimer(RequestLocalDateTime, null, 86400000, 86400000);
|
||||
// Send Push Notification Action request:
|
||||
|
||||
_dailyTimeRequestTimer.Reset(86400000, 86400000);
|
||||
const string requestId = "InitialPushRequest";
|
||||
|
||||
|
||||
var actionRequest =
|
||||
string.Format("<RequestAction>\n<RequestID>{0}</RequestID>\n", requestId) +
|
||||
"<ActionID>RegisterPushModel</ActionID>\n" +
|
||||
"<Parameters>\n" +
|
||||
"<Parameter ID='Enabled' Value='1' />\n" +
|
||||
"<Parameter ID='RequestID' Value='PushNotification' />\n" +
|
||||
"<Parameter ID='Start' Value='00:00:00' />\n" +
|
||||
"<Parameter ID='HourSpan' Value='24' />\n" +
|
||||
"<Parameter ID='Field' Value='MeetingID' />\n" +
|
||||
"<Parameter ID='Field' Value='RVMeetingID' />\n" +
|
||||
"<Parameter ID='Field' Value='InstanceID' />\n" +
|
||||
"<Parameter ID='Field' Value='dtStart' />\n" +
|
||||
"<Parameter ID='Field' Value='dtEnd' />\n" +
|
||||
"<Parameter ID='Field' Value='Subject' />\n" +
|
||||
"<Parameter ID='Field' Value='Organizer' />\n" +
|
||||
"<Parameter ID='Field' Value='IsEvent' />\n" +
|
||||
"<Parameter ID='Field' Value='IsPrivate' />\n" +
|
||||
"<Parameter ID='Field' Value='IsExchangePrivate' />\n" +
|
||||
"<Parameter ID='Field' Value='LiveMeeting' />\n" +
|
||||
"<Parameter ID='Field' Value='ShareDocPath' />\n" +
|
||||
"<Parameter ID='Field' Value='PhoneNo' />\n" +
|
||||
"<Parameter ID='Field' Value='ParticipantCode' />\n" +
|
||||
"</Parameters>\n" +
|
||||
"</RequestAction>\n";
|
||||
|
||||
Debug.Console(2, this, "Sending Fusion ActionRequest: \n{0}", actionRequest);
|
||||
|
||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.ActionQuery.StringValue = actionRequest;
|
||||
|
||||
GetCustomProperties();
|
||||
|
||||
// Request current Fusion Server Time
|
||||
RequestLocalDateTime(null);
|
||||
|
||||
// Setup timer to request time daily
|
||||
if (_dailyTimeRequestTimer != null && !_dailyTimeRequestTimer.Disposed)
|
||||
{
|
||||
_dailyTimeRequestTimer.Stop();
|
||||
_dailyTimeRequestTimer.Dispose();
|
||||
}
|
||||
|
||||
_dailyTimeRequestTimer = new CTimer(RequestLocalDateTime, null, 86400000, 86400000);
|
||||
|
||||
_dailyTimeRequestTimer.Reset(86400000, 86400000);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -597,7 +605,6 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
var tokens = command.Split(' ');
|
||||
|
||||
//var meetingId = tokens[0]; never used, commenting out for now
|
||||
extendMinutes = Int32.Parse(tokens[1]);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -720,16 +727,19 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var requestId = actionResponse["RequestID"];
|
||||
|
||||
if (requestId.InnerText != "InitialPushRequest")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (actionResponse["ActionID"].InnerText != "RegisterPushModel")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var parameters = actionResponse["Parameters"];
|
||||
|
||||
foreach (var isRegistered in from XmlElement parameter in parameters
|
||||
@@ -750,8 +760,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
_pushNotificationTimer = new CTimer(RequestFullRoomSchedule, null,
|
||||
PushNotificationTimeout, PushNotificationTimeout);
|
||||
_pushNotificationTimer.Reset(PushNotificationTimeout,
|
||||
PushNotificationTimeout);
|
||||
_pushNotificationTimer.Reset(PushNotificationTimeout, PushNotificationTimeout);
|
||||
break;
|
||||
case 0:
|
||||
_isRegisteredForSchedulePushNotifications = false;
|
||||
@@ -760,8 +769,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
_pushNotificationTimer.Stop();
|
||||
_pushNotificationTimer.Dispose();
|
||||
}
|
||||
_pollTimer = new CTimer(RequestFullRoomSchedule, null,
|
||||
SchedulePollInterval, SchedulePollInterval);
|
||||
_pollTimer = new CTimer(RequestFullRoomSchedule, null, SchedulePollInterval,
|
||||
SchedulePollInterval);
|
||||
_pollTimer.Reset(SchedulePollInterval, SchedulePollInterval);
|
||||
break;
|
||||
}
|
||||
@@ -844,7 +853,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
if (el.Name == "CustomField")
|
||||
{
|
||||
customProperty.Id = el.Attributes["ID"].Value;
|
||||
customProperty.ID = el.Attributes["ID"].Value;
|
||||
}
|
||||
|
||||
foreach (XmlElement elm in el)
|
||||
@@ -1037,9 +1046,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
uint i = 1;
|
||||
foreach (var kvp in setTopBoxes)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
TryAddRouteActionSigs(JoinMap.Display1SetTopBoxSourceStart.Metadata.Description + " " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 5) // We only have five spots
|
||||
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1049,9 +1058,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
i = 1;
|
||||
foreach (var kvp in discPlayers)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.Metadata.Description + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 5) // We only have five spots
|
||||
if (i > JoinMap.Display1DiscPlayerSourceStart.JoinSpan) // We only have five spots
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1061,9 +1070,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
i = 1;
|
||||
foreach (var kvp in laptops)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.Metadata.Description + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 10) // We only have ten spots???
|
||||
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1072,8 +1081,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
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;
|
||||
usageDevice.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1092,8 +1100,6 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
var deviceTracker = sender as UsageTracking;
|
||||
|
||||
//var configDevice = ConfigReader.ConfigObject.Devices.Where(d => d.Key.Equals(deviceTracker.Parent)); never used...
|
||||
|
||||
if (deviceTracker == null)
|
||||
{
|
||||
return;
|
||||
@@ -1135,15 +1141,14 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
_sourceToFeedbackSigs.Add(pSrc, sigD.InputSig);
|
||||
|
||||
// And respond to selection in Fusion
|
||||
sigD.OutputSig.SetSigFalseAction(
|
||||
() =>
|
||||
sigD.OutputSig.SetSigFalseAction(() =>
|
||||
{
|
||||
var runRouteAction = Room as IRunRouteAction;
|
||||
if (runRouteAction != null)
|
||||
{
|
||||
var runRouteAction = Room as IRunRouteAction;
|
||||
if (runRouteAction != null)
|
||||
{
|
||||
runRouteAction.RunRouteAction(routeKey, Room.SourceListKey);
|
||||
}
|
||||
});
|
||||
runRouteAction.RunRouteAction(routeKey, Room.SourceListKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -1190,12 +1195,12 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
attrNum = attrNum + touchpanelNum;
|
||||
|
||||
if (attrNum > 10)
|
||||
if (attrNum > JoinMap.XpanelOnlineStart.JoinSpan)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
attrName = "Online - XPanel " + attrNum;
|
||||
attrNum += 160;
|
||||
attrName = JoinMap.XpanelOnlineStart.Metadata.Description + " " + attrNum;
|
||||
attrNum += JoinMap.XpanelOnlineStart.JoinNumber;
|
||||
|
||||
touchpanelNum++;
|
||||
}
|
||||
@@ -1203,12 +1208,12 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
attrNum = attrNum + xpanelNum;
|
||||
|
||||
if (attrNum > 10)
|
||||
if (attrNum > JoinMap.TouchpanelOnlineStart.JoinSpan)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
attrName = "Online - Touch Panel " + attrNum;
|
||||
attrNum += 150;
|
||||
attrName = JoinMap.TouchpanelOnlineStart.Metadata.Description + " " + attrNum;
|
||||
attrNum += JoinMap.TouchpanelOnlineStart.JoinNumber;
|
||||
|
||||
xpanelNum++;
|
||||
}
|
||||
@@ -1218,12 +1223,12 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
if (dev is DisplayBase)
|
||||
{
|
||||
attrNum = attrNum + displayNum;
|
||||
if (attrNum > 10)
|
||||
if (attrNum > JoinMap.DisplayOnlineStart.JoinSpan)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
attrName = "Online - Display " + attrNum;
|
||||
attrNum += 170;
|
||||
attrName = JoinMap.DisplayOnlineStart.Metadata.Description + " " + attrNum;
|
||||
attrNum += JoinMap.DisplayOnlineStart.JoinNumber;
|
||||
|
||||
displayNum++;
|
||||
}
|
||||
@@ -1259,15 +1264,14 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
//Setup Display Usage Monitoring
|
||||
|
||||
var displays = DeviceManager.AllDevices.Where(d => d is TwoWayDisplayBase);
|
||||
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
|
||||
|
||||
// Consider updating this in multiple display systems
|
||||
|
||||
foreach (var display in displays.Cast<TwoWayDisplayBase>())
|
||||
foreach (var display in displays.Cast<DisplayBase>())
|
||||
{
|
||||
display.UsageTracker = new UsageTracking(display) {UsageIsTracked = true};
|
||||
display.UsageTracker.DeviceUsageEnded +=
|
||||
UsageTracker_DeviceUsageEnded;
|
||||
display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||
}
|
||||
|
||||
var hasDefaultDisplay = Room as IHasDefaultDisplay;
|
||||
@@ -1275,8 +1279,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var defaultDisplay = hasDefaultDisplay.DefaultDisplay as TwoWayDisplayBase;
|
||||
var defaultDisplay = hasDefaultDisplay.DefaultDisplay as DisplayBase;
|
||||
if (defaultDisplay == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
|
||||
@@ -1301,17 +1304,49 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
// 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)
|
||||
|
||||
MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay);
|
||||
|
||||
|
||||
var deviceConfig =
|
||||
ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
|
||||
|
||||
//Check for existing asset in GUIDs collection
|
||||
|
||||
FusionAsset tempAsset;
|
||||
|
||||
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||
{
|
||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new asset
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
|
||||
defaultDisplay.Name, "Display", "");
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
|
||||
tempAsset.InstanceId);
|
||||
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
|
||||
MapDisplayToRoomJoins(1, 158, defaultDisplay);
|
||||
var defaultTwoWayDisplay = defaultDisplay as IHasPowerControlWithFeedback;
|
||||
if (defaultTwoWayDisplay != null)
|
||||
{
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
if (defaultDisplay is IDisplayUsage)
|
||||
{
|
||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
}
|
||||
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
}
|
||||
|
||||
|
||||
// Use extension methods
|
||||
dispAsset.TrySetMakeModel(defaultDisplay);
|
||||
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -1326,7 +1361,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
/// <param name="display"></param>
|
||||
/// <param name="displayIndex"></param>
|
||||
/// a
|
||||
protected virtual void MapDisplayToRoomJoins(int displayIndex, int joinOffset, TwoWayDisplayBase display)
|
||||
protected virtual void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display)
|
||||
{
|
||||
var displayName = string.Format("Display {0} - ", displayIndex);
|
||||
|
||||
@@ -1337,22 +1372,20 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
return;
|
||||
}
|
||||
// Display volume
|
||||
var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01",
|
||||
var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.Metadata.Description,
|
||||
eSigIoMask.InputOutputSig);
|
||||
defaultDisplayVolume.OutputSig.UserObject =
|
||||
new Action<ushort>(b =>
|
||||
{
|
||||
var basicVolumeWithFeedback = display as IBasicVolumeWithFeedback;
|
||||
if (basicVolumeWithFeedback != null)
|
||||
{
|
||||
basicVolumeWithFeedback.SetVolume(b);
|
||||
}
|
||||
});
|
||||
var volumeWithFeedback = display as IBasicVolumeWithFeedback;
|
||||
if (volumeWithFeedback != null)
|
||||
defaultDisplayVolume.OutputSig.UserObject = new Action<ushort>(b =>
|
||||
{
|
||||
volumeWithFeedback.VolumeLevelFeedback.LinkInputSig(defaultDisplayVolume.InputSig);
|
||||
}
|
||||
var basicVolumeWithFeedback = display as IBasicVolumeWithFeedback;
|
||||
if (basicVolumeWithFeedback == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
basicVolumeWithFeedback.SetVolume(b);
|
||||
basicVolumeWithFeedback.VolumeLevelFeedback.LinkInputSig(defaultDisplayVolume.InputSig);
|
||||
});
|
||||
|
||||
|
||||
// Power on
|
||||
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint) joinOffset, displayName + "Power On",
|
||||
@@ -1364,10 +1397,10 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
display.PowerOn();
|
||||
}
|
||||
});
|
||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
|
||||
// Power Off
|
||||
//var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 1,displayName + "Power Off", eSigIoMask.InputOutputSig); //not used
|
||||
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 1, displayName + "Power Off",
|
||||
eSigIoMask.InputOutputSig);
|
||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
@@ -1375,36 +1408,44 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
display.PowerOff();
|
||||
}
|
||||
});
|
||||
|
||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
|
||||
|
||||
var defaultTwoWayDisplay = display as IHasPowerControlWithFeedback;
|
||||
if (defaultTwoWayDisplay != null)
|
||||
{
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkComplementInputSig(defaultDisplayPowerOff.InputSig);
|
||||
}
|
||||
|
||||
// Current Source
|
||||
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 8,
|
||||
displayName + "Source None", eSigIoMask.InputOutputSig);
|
||||
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b =>
|
||||
{
|
||||
if (b)
|
||||
if (!b)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var runRouteAction = Room as IRunRouteAction;
|
||||
if (runRouteAction != null)
|
||||
{
|
||||
runRouteAction.RunRouteAction("roomOff", Room.SourceListKey);
|
||||
var runRouteAction = Room as IRunRouteAction;
|
||||
if (runRouteAction != null)
|
||||
{
|
||||
runRouteAction.RunRouteAction("roomOff", Room.SourceListKey);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void SetUpError()
|
||||
{
|
||||
// Roll up ALL device errors
|
||||
_errorMessageRollUp = new StatusMonitorCollection(this);
|
||||
foreach (var md in DeviceManager.GetDevices().OfType<ICommunicationMonitor>())
|
||||
foreach (var dev in DeviceManager.GetDevices())
|
||||
{
|
||||
_errorMessageRollUp.AddMonitor(md.CommunicationMonitor);
|
||||
Debug.Console(2, this, "Adding '{0}' to room's overall error monitor",
|
||||
md.CommunicationMonitor.Parent.Key);
|
||||
var md = dev as ICommunicationMonitor;
|
||||
if (md != null)
|
||||
{
|
||||
_errorMessageRollUp.AddMonitor(md.CommunicationMonitor);
|
||||
Debug.Console(2, this, "Adding '{0}' to room's overall error monitor",
|
||||
md.CommunicationMonitor.Parent.Key);
|
||||
}
|
||||
}
|
||||
_errorMessageRollUp.Start();
|
||||
FusionRoom.ErrorMessage.InputSig.StringValue = _errorMessageRollUp.Message;
|
||||
@@ -1460,7 +1501,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
occSensorAsset.RoomOccupied.AddSigToRVIFile = true;
|
||||
|
||||
//var occSensorShutdownMinutes = FusionRoom.CreateOffsetUshortSig(70, "Occ Shutdown - Minutes",eSigIoMask.InputOutputSig); //not used
|
||||
//var occSensorShutdownMinutes = FusionRoom.CreateOffsetUshortSig(70, "Occ Shutdown - Minutes", eSigIoMask.InputOutputSig);
|
||||
|
||||
// Tie to method on occupancy object
|
||||
//occSensorShutdownMinutes.OutputSig.UserObject(new Action(ushort)(b => Room.OccupancyObj.SetShutdownMinutes(b));
|
||||
@@ -1491,7 +1532,6 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Convert.ToInt32(capture.Groups[1].Value);
|
||||
}
|
||||
|
||||
@@ -1530,10 +1570,12 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
// The sig/UO method: Need separate handlers for fixed and user sigs, all flavors,
|
||||
// even though they all contain sigs.
|
||||
|
||||
var sigData = (args.UserConfiguredSigDetail as BooleanSigDataFixedName);
|
||||
var sigData = args.UserConfiguredSigDetail as BooleanSigDataFixedName;
|
||||
|
||||
BoolOutputSig outSig;
|
||||
if (sigData != null)
|
||||
{
|
||||
var outSig = sigData.OutputSig;
|
||||
outSig = sigData.OutputSig;
|
||||
if (outSig.UserObject is Action<bool>)
|
||||
{
|
||||
(outSig.UserObject as Action<bool>).Invoke(outSig.BoolValue);
|
||||
@@ -1554,19 +1596,18 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var aOutSig = attrData.OutputSig;
|
||||
if (aOutSig.UserObject is Action<bool>)
|
||||
outSig = attrData.OutputSig;
|
||||
if (outSig.UserObject is Action<bool>)
|
||||
{
|
||||
(aOutSig.UserObject as Action<bool>).Invoke(aOutSig.BoolValue);
|
||||
(outSig.UserObject as Action<bool>).Invoke(outSig.BoolValue);
|
||||
}
|
||||
else if (aOutSig.UserObject is Action<ushort>)
|
||||
else if (outSig.UserObject is Action<ushort>)
|
||||
{
|
||||
(aOutSig.UserObject as Action<ushort>).Invoke(aOutSig.UShortValue);
|
||||
(outSig.UserObject as Action<ushort>).Invoke(outSig.UShortValue);
|
||||
}
|
||||
else if (aOutSig.UserObject is Action<string>)
|
||||
else if (outSig.UserObject is Action<string>)
|
||||
{
|
||||
(aOutSig.UserObject as Action<string>).Invoke(aOutSig.StringValue);
|
||||
(outSig.UserObject as Action<string>).Invoke(outSig.StringValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1702,12 +1743,12 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
FusionCustomProperties = new List<FusionCustomProperty>();
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Location { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string TimeZone { get; set; }
|
||||
public string WebcamUrl { get; set; }
|
||||
public string WebcamURL { get; set; }
|
||||
public string BacklogMsg { get; set; }
|
||||
public string SubErrorMsg { get; set; }
|
||||
public string EmailInfo { get; set; }
|
||||
@@ -1722,10 +1763,10 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
public FusionCustomProperty(string id)
|
||||
{
|
||||
Id = id;
|
||||
ID = id;
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string ID { get; set; }
|
||||
public string CustomFieldName { get; set; }
|
||||
public string CustomFieldType { get; set; }
|
||||
public string CustomFieldValue { get; set; }
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
public class EssentialsHuddleSpaceRoomFusionRoomJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
|
||||
// Processor Attributes
|
||||
[JoinName("ProcessorIp1")]
|
||||
public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Info - Processor - IP 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - IP 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorIp2")]
|
||||
public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1, AttributeName = "Info - Processor - IP 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - IP 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorGateway")]
|
||||
public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1, AttributeName = "Info - Processor - Gateway" },
|
||||
new JoinMetadata { Description = "Info - Processor - Gateway", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorHostname")]
|
||||
public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1, AttributeName = "Info - Processor - Hostname" },
|
||||
new JoinMetadata { Description = "Info - Processor - Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorDomain")]
|
||||
public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - Domain" },
|
||||
new JoinMetadata { Description = "Info - Processor - Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorDns1")]
|
||||
public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - DNS 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorDns2")]
|
||||
public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1, AttributeName = "Info - Processor - DNS 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorMac1")]
|
||||
public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1, AttributeName = "Info - Processor - MAC 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - MAC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorMac2")]
|
||||
public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1, AttributeName = "Info - Processor - MAC 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - MAC 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorNetMask1")]
|
||||
public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - Net Mask 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorNetMask2")]
|
||||
public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - Net Mask 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorFirmware")]
|
||||
public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1, AttributeName = "Info - Processor - Firmware" },
|
||||
new JoinMetadata { Description = "Info - Processor - Firmware", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProgramNameStart")]
|
||||
public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10, AttributeName = "Info - Processor - Program" },
|
||||
new JoinMetadata { Description = "Info - Processor - Program", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorReboot")]
|
||||
public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1, AttributeName = "Processor - Reboot" },
|
||||
new JoinMetadata { Description = "Processor - Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
// Volume Controls
|
||||
[JoinName("VolumeFader1")]
|
||||
public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Volume - Fader01" },
|
||||
new JoinMetadata { Description = "Volume - Fader01", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog });
|
||||
|
||||
// Codec Info
|
||||
[JoinName("VcCodecInCall")]
|
||||
public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1, AttributeName = "Conf - VC 1 In Call" },
|
||||
new JoinMetadata { Description = "Conf - VC 1 In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("VcCodecOnline")]
|
||||
public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1, AttributeName = "Online - VC 1" },
|
||||
new JoinMetadata { Description = "Online - VC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("VcCodecIpAddress")]
|
||||
public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1, AttributeName = "IP Address - VC" },
|
||||
new JoinMetadata { Description = "IP Address - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("VcCodecIpPort")]
|
||||
public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1, AttributeName = "IP Port - VC" },
|
||||
new JoinMetadata { Description = "IP Port - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
// Source Attributes
|
||||
[JoinName("Display1CurrentSourceName")]
|
||||
public JoinDataComplete Display1CurrentSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1, AttributeName = "Display 1 - Current Source" },
|
||||
new JoinMetadata { Description = "Display 1 - Current Source", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
|
||||
// Device Online Status
|
||||
[JoinName("TouchpanelOnlineStart")]
|
||||
public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10, AttributeName = "Online - Touch Panel" },
|
||||
new JoinMetadata { Description = "Online - Touch Panel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("XpanelOnlineStart")]
|
||||
public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5, AttributeName = "Online - XPanel" },
|
||||
new JoinMetadata { Description = "Online - XPanel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("DisplayOnlineStart")]
|
||||
public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10, AttributeName = "Online - Display" },
|
||||
new JoinMetadata { Description = "Online - Display", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Display1LaptopSourceStart")]
|
||||
public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 5, AttributeName = "Display 1 - Source Laptop" },
|
||||
new JoinMetadata { Description = "Display 1 - Source Laptop", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Display1DiscPlayerSourceStart")]
|
||||
public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 181, JoinSpan = 5, AttributeName = "Display 1 - Source Disc Player" },
|
||||
new JoinMetadata { Description = "Display 1 - Source Disc Player", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Display1SetTopBoxSourceStart")]
|
||||
public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5, AttributeName = "Display 1 - Source TV" },
|
||||
new JoinMetadata { Description = "Display 1 - Source TV", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
// Display 1
|
||||
[JoinName("Display1Start")]
|
||||
public JoinDataComplete Display1Start = new JoinDataComplete(new JoinData { JoinNumber = 158, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Display 1 Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when instantiating this Join Map without inheriting from it
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart)
|
||||
: base(joinStart, typeof(EssentialsHuddleSpaceRoomFusionRoomJoinMap))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when extending this Join map
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
/// <param name="type">Type of the child join map</param>
|
||||
public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart, Type type) : base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharpPro;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
|
||||
{
|
||||
private BooleanSigData _codecIsInCall;
|
||||
|
||||
private readonly EssentialsHuddleVtc1Room _room;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsHuddleSpaceFusionSystemControllerBase
|
||||
|
||||
protected override void SetUpDisplay()
|
||||
{
|
||||
base.SetUpDisplay();
|
||||
|
||||
var defaultDisplay = _room.DefaultDisplay as TwoWayDisplayBase;
|
||||
|
||||
if (defaultDisplay == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
|
||||
return;
|
||||
}
|
||||
|
||||
var deviceConfig =
|
||||
ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
|
||||
|
||||
//Check for existing asset in GUIDs collection
|
||||
|
||||
FusionAsset tempAsset;
|
||||
|
||||
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||
{
|
||||
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new asset
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
|
||||
defaultDisplay.Name, "Display", "");
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var dispPowerOnAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
defaultDisplay.PowerOn();
|
||||
}
|
||||
});
|
||||
var dispPowerOffAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
defaultDisplay.PowerOff();
|
||||
}
|
||||
});
|
||||
|
||||
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
|
||||
tempAsset.InstanceId);
|
||||
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
|
||||
// Use extension methods
|
||||
dispAsset.TrySetMakeModel(defaultDisplay);
|
||||
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void codec_CallStatusChange(object sender, Devices.Codec.CodecCallStatusItemChangeEventArgs e)
|
||||
{
|
||||
var codec = _room.VideoCodec;
|
||||
|
||||
_codecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ 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
|
||||
{
|
||||
@@ -41,43 +40,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);
|
||||
|
||||
@@ -96,7 +95,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);
|
||||
|
||||
@@ -12,6 +12,7 @@ using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash_Essentials_Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using Activator = System.Activator;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
@@ -14,7 +17,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
public static class Scheduler
|
||||
{
|
||||
private static Dictionary<string, ScheduledEventGroup> EventGroups = new Dictionary<string,ScheduledEventGroup>();
|
||||
private static readonly Dictionary<string, ScheduledEventGroup> EventGroups = new Dictionary<string,ScheduledEventGroup>();
|
||||
|
||||
static Scheduler()
|
||||
{
|
||||
@@ -49,7 +52,6 @@ namespace PepperDash.Essentials.Core
|
||||
/// <summary>
|
||||
/// Adds the event group to the global list
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static void AddEventGroup(ScheduledEventGroup eventGroup)
|
||||
{
|
||||
@@ -67,6 +69,13 @@ namespace PepperDash.Essentials.Core
|
||||
if(!EventGroups.ContainsKey(eventGroup.Name))
|
||||
EventGroups.Remove(eventGroup.Name);
|
||||
}
|
||||
|
||||
public static ScheduledEventGroup GetEventGroup(string key)
|
||||
{
|
||||
ScheduledEventGroup returnValue;
|
||||
|
||||
return EventGroups.TryGetValue(key, out returnValue) ? returnValue : null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SchedulerUtilities
|
||||
@@ -135,5 +144,90 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
return isMatch;
|
||||
}
|
||||
|
||||
public static bool CheckEventTimeForMatch(ScheduledEvent evnt, DateTime time)
|
||||
{
|
||||
return evnt.DateAndTime.Hour == time.Hour && evnt.DateAndTime.Minute == time.Minute;
|
||||
}
|
||||
|
||||
public static bool CheckEventRecurrenceForMatch(ScheduledEvent evnt, ScheduledEventCommon.eWeekDays days)
|
||||
{
|
||||
return evnt.Recurrence.RecurrenceDays == days;
|
||||
}
|
||||
|
||||
public static void CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group, ScheduledEvent.UserEventCallBack handler)
|
||||
{
|
||||
if (group == null)
|
||||
{
|
||||
Debug.Console(0, "Unable to create event. Group is null");
|
||||
return;
|
||||
}
|
||||
var scheduledEvent = new ScheduledEvent(config.Key, group)
|
||||
{
|
||||
Acknowledgeable = config.Acknowledgeable,
|
||||
Persistent = config.Persistent
|
||||
};
|
||||
|
||||
scheduledEvent.UserCallBack += handler;
|
||||
|
||||
scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday);
|
||||
|
||||
var eventTime = DateTime.Parse(config.Time);
|
||||
|
||||
if (DateTime.Now > eventTime)
|
||||
{
|
||||
eventTime = eventTime.AddDays(1);
|
||||
}
|
||||
|
||||
Debug.Console(2, "[Scheduler] Current Date day of week: {0} recurrence days: {1}", eventTime.DayOfWeek,
|
||||
config.Days);
|
||||
|
||||
var dayOfWeekConverted = ConvertDayOfWeek(eventTime);
|
||||
|
||||
Debug.Console(1, "[Scheduler] eventTime Day: {0}", dayOfWeekConverted);
|
||||
|
||||
while (!dayOfWeekConverted.IsFlagSet(config.Days))
|
||||
{
|
||||
eventTime = eventTime.AddDays(1);
|
||||
|
||||
dayOfWeekConverted = ConvertDayOfWeek(eventTime);
|
||||
}
|
||||
|
||||
scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime);
|
||||
|
||||
scheduledEvent.Recurrence.Weekly(config.Days);
|
||||
|
||||
if (config.Enable)
|
||||
{
|
||||
scheduledEvent.Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
scheduledEvent.Disable();
|
||||
}
|
||||
}
|
||||
|
||||
private static ScheduledEventCommon.eWeekDays ConvertDayOfWeek(DateTime eventTime)
|
||||
{
|
||||
return (ScheduledEventCommon.eWeekDays) Enum.Parse(typeof(ScheduledEventCommon.eWeekDays), eventTime.DayOfWeek.ToString(), true);
|
||||
}
|
||||
|
||||
private static bool IsFlagSet<T>(this T value, T flag) where T : struct
|
||||
{
|
||||
CheckIsEnum<T>(true);
|
||||
|
||||
var lValue = Convert.ToInt64(value);
|
||||
var lFlag = Convert.ToInt64(flag);
|
||||
|
||||
return (lValue & lFlag) != 0;
|
||||
}
|
||||
|
||||
private static void CheckIsEnum<T>(bool withFlags)
|
||||
{
|
||||
if (!typeof(T).IsEnum)
|
||||
throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName));
|
||||
if (withFlags && !Attribute.IsDefined(typeof(T), typeof(FlagsAttribute)))
|
||||
throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", typeof(T).FullName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,7 +266,7 @@ namespace PepperDash.Essentials.Core
|
||||
@"Join Number: {0} | JoinSpan: '{1}' | Description: '{2}' | Type: '{3}' | Capabilities: '{4}'",
|
||||
join.Value.JoinNumber,
|
||||
join.Value.JoinSpan,
|
||||
String.IsNullOrEmpty(join.Value.Metadata.Description) ? join.Value.Metadata.Label: join.Value.Metadata.Description,
|
||||
String.IsNullOrEmpty(join.Value.Metadata.Description) ? join.Value.Metadata.Label : join.Value.Metadata.Description,
|
||||
join.Value.Metadata.JoinType.ToString(),
|
||||
join.Value.Metadata.JoinCapabilities.ToString());
|
||||
}
|
||||
@@ -288,7 +288,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "No mathcing key found in join map for: '{0}'", customJoinData.Key);
|
||||
Debug.Console(2, "No matching key found in join map for: '{0}'", customJoinData.Key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,7 +327,10 @@ namespace PepperDash.Essentials.Core
|
||||
None = 0,
|
||||
ToSIMPL = 1,
|
||||
FromSIMPL = 2,
|
||||
ToFromSIMPL = ToSIMPL | FromSIMPL
|
||||
ToFromSIMPL = ToSIMPL | FromSIMPL,
|
||||
ToFusion = 4,
|
||||
FromFusion = 8,
|
||||
ToFromFusion = ToFusion | FromFusion,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -340,7 +343,7 @@ namespace PepperDash.Essentials.Core
|
||||
DigitalAnalog = Digital | Analog,
|
||||
DigitalSerial = Digital | Serial,
|
||||
AnalogSerial = Analog | Serial,
|
||||
DigitalAnalogSerial = Digital | Analog | Serial
|
||||
DigitalAnalogSerial = Digital | Analog | Serial,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -394,7 +397,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data describing the join. Can be
|
||||
/// Data describing the join. Can be overridden from configuratino
|
||||
/// </summary>
|
||||
public class JoinData
|
||||
{
|
||||
@@ -408,6 +411,11 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
[JsonProperty("joinSpan")]
|
||||
public uint JoinSpan { get; set; }
|
||||
/// <summary>
|
||||
/// Fusion Attribute Name (optional)
|
||||
/// </summary>
|
||||
[JsonProperty("attributeName")]
|
||||
public string AttributeName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -419,6 +427,10 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
private JoinData _data;
|
||||
public JoinMetadata Metadata { get; set; }
|
||||
/// <summary>
|
||||
/// To store some future information as you please
|
||||
/// </summary>
|
||||
public object UserObject { get; private set; }
|
||||
|
||||
public JoinDataComplete(JoinData data, JoinMetadata metadata)
|
||||
{
|
||||
@@ -449,6 +461,11 @@ namespace PepperDash.Essentials.Core
|
||||
get { return _data.JoinSpan; }
|
||||
}
|
||||
|
||||
public string AttributeName
|
||||
{
|
||||
get { return _data.AttributeName; }
|
||||
}
|
||||
|
||||
public void SetCustomJoinData(JoinData customJoinData)
|
||||
{
|
||||
_data = customJoinData;
|
||||
|
||||
@@ -4,7 +4,7 @@ using Crestron.SimplSharpPro.GeneralIO;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Bridges.JoinMaps;
|
||||
using PepperDash_Essentials_Core.Bridges.JoinMaps;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -186,30 +186,20 @@
|
||||
<Compile Include="Device Info\DeviceInfo.cs" />
|
||||
<Compile Include="Device Info\DeviceInfoEventArgs.cs" />
|
||||
<Compile Include="Device Info\IDeviceInfoProvider.cs" />
|
||||
<Compile Include="Devices\Base Classes\AudioCodecBase.cs" />
|
||||
<Compile Include="Devices\Base Classes\CameraBase.cs" />
|
||||
<Compile Include="Devices\Base Classes\EssentialsBridgeableDevice.cs" />
|
||||
<Compile Include="Devices\Base Classes\EssentialsDevice.cs" />
|
||||
<Compile Include="Devices\CodecCommandWithLabel.cs" />
|
||||
<Compile Include="Devices\Interfaces\CameraControl.cs" />
|
||||
<Compile Include="Devices\Interfaces\CodecInterfaces.cs" />
|
||||
<Compile Include="Devices\CodecInterfaces.cs" />
|
||||
<Compile Include="Devices\CrestronProcessor.cs" />
|
||||
<Compile Include="Devices\DestinationListItem.cs" />
|
||||
<Compile Include="Devices\Base Classes\DeviceApiBase.cs" />
|
||||
<Compile Include="Devices\DeviceApiBase.cs" />
|
||||
<Compile Include="Devices\DeviceFeedbackExtensions.cs" />
|
||||
<Compile Include="Devices\EssentialsBridgeableDevice.cs" />
|
||||
<Compile Include="Devices\EssentialsDevice.cs" />
|
||||
<Compile Include="Devices\GenericIRController.cs" />
|
||||
<Compile Include="Devices\IDspPreset.cs" />
|
||||
<Compile Include="Devices\Interfaces\IHasCameraPresets.cs" />
|
||||
<Compile Include="Devices\Interfaces\IProjectorInterfaces.cs" />
|
||||
<Compile Include="Devices\IProjectorInterfaces.cs" />
|
||||
<Compile Include="Devices\PC\InRoomPc.cs" />
|
||||
<Compile Include="Devices\PC\Laptop.cs" />
|
||||
<Compile Include="Devices\Base Classes\ReconfigurableDevice.cs" />
|
||||
<Compile Include="Devices\Base Classes\VideoCodecBase.cs" />
|
||||
<Compile Include="Devices\RoomPresets.cs" />
|
||||
<Compile Include="Devices\ReconfigurableDevice.cs" />
|
||||
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\IHasExternalSourceSwitching.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\IHasParticipants.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\Codec\IHasSelfviewPosition.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\ITvPresetsProvider.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\LanguageLabel.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\ILanguageProvider.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasBranding.cs" />
|
||||
@@ -217,24 +207,6 @@
|
||||
<Compile Include="DeviceTypeInterfaces\IHasFarEndContentStatus.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasPhoneDialing.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IMobileControl.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="Factory\DeviceFactory.cs" />
|
||||
<Compile Include="Factory\IDeviceFactory.cs" />
|
||||
<Compile Include="Factory\ReadyEventArgs.cs" />
|
||||
@@ -244,12 +216,11 @@
|
||||
<Compile Include="Feedbacks\IntFeedback.cs" />
|
||||
<Compile Include="Feedbacks\SerialFeedback.cs" />
|
||||
<Compile Include="Feedbacks\StringFeedback.cs" />
|
||||
<Compile Include="Fusion\EssentialsDualDisplayFusionController.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleVtc1FusionController.cs" />
|
||||
<Compile Include="Fusion\FusionCustomPropertiesBridge.cs" />
|
||||
<Compile Include="Fusion\FusionEventHandlers.cs" />
|
||||
<Compile Include="Fusion\FusionProcessorQueries.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs" />
|
||||
<Compile Include="Fusion\FusionRviDataClasses.cs" />
|
||||
<Compile Include="Gateways\CenRfgwController.cs" />
|
||||
<Compile Include="Gateways\EssentialsRfGatewayConfig.cs" />
|
||||
@@ -281,8 +252,8 @@
|
||||
<Compile Include="Config\InfoConfig.cs" />
|
||||
<Compile Include="Config\DeviceConfig.cs" />
|
||||
<Compile Include="Devices\DisplayUiConstants.cs" />
|
||||
<Compile Include="Devices\Interfaces\IUsageTracking.cs" />
|
||||
<Compile Include="Devices\Base Classes\DeviceJsonApi.cs" />
|
||||
<Compile Include="Devices\IUsageTracking.cs" />
|
||||
<Compile Include="Devices\DeviceJsonApi.cs" />
|
||||
<Compile Include="Devices\SourceListItem.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IDisplayBasic.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IDumbSource.cs" />
|
||||
@@ -299,7 +270,7 @@
|
||||
<Compile Include="DeviceTypeInterfaces\ITransport.cs" />
|
||||
<Compile Include="Devices\GenericMonitoredTcpDevice.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\INumeric.cs" />
|
||||
<Compile Include="Devices\Interfaces\IVolumeAndAudioInterfaces.cs" />
|
||||
<Compile Include="Devices\IVolumeAndAudioInterfaces.cs" />
|
||||
<Compile Include="Display\BasicIrDisplay.cs" />
|
||||
<Compile Include="Feedbacks\BoolFeedbackOneShot.cs" />
|
||||
<Compile Include="Ramps and Increments\NumericalHelpers.cs" />
|
||||
@@ -307,24 +278,11 @@
|
||||
<Compile Include="Remotes\ButtonExtensions.cs" />
|
||||
<Compile Include="Remotes\CrestronRemotePropertiesConfig.cs" />
|
||||
<Compile Include="Remotes\Hrxx0WirelessRemoteController.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="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
|
||||
<Compile Include="Room\EssentialsRoomBase.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" />
|
||||
<Compile Include="Room\Interfaces.cs" />
|
||||
<Compile Include="Room\iOccupancyStatusProvider.cs" />
|
||||
<Compile Include="Routing\DummyRoutingInputsDevice.cs" />
|
||||
<Compile Include="Routing\ICardPortsDevice.cs" />
|
||||
<Compile Include="InUseTracking\IInUseTracking.cs" />
|
||||
@@ -335,10 +293,10 @@
|
||||
<Compile Include="Monitoring\StatusMonitorBase.cs" />
|
||||
<Compile Include="Monitoring\Interfaces.cs" />
|
||||
<Compile Include="Monitoring\GenericCommunicationMonitor.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\AudioInterfaces.cs" />
|
||||
<Compile Include="Devices\IAttachVideoStatusExtensions.cs" />
|
||||
<Compile Include="Devices\IHasFeedbacks.cs" />
|
||||
<Compile Include="Devices\SmartObjectBaseTypes.cs" />
|
||||
<Compile Include="Devices\PresentationDeviceType.cs" />
|
||||
<Compile Include="Display\MockDisplay.cs" />
|
||||
<Compile Include="Ethernet\EthernetStatistics.cs" />
|
||||
@@ -383,11 +341,11 @@
|
||||
<Compile Include="Devices\IrOutputPortController.cs" />
|
||||
<Compile Include="Display\DisplayBase.cs" />
|
||||
<Compile Include="Feedbacks\FeedbackBase.cs" />
|
||||
<Compile Include="Rooms\Room.cs" />
|
||||
<Compile Include="Room\Room.cs" />
|
||||
<Compile Include="SmartObjects\SubpageReferencList\SourceListSubpageReferenceList.cs" />
|
||||
<Compile Include="Touchpanels\ModalDialog.cs" />
|
||||
<Compile Include="TriListBridges\HandlerBridge.cs" />
|
||||
<Compile Include="Devices\Interfaces\Interfaces.cs" />
|
||||
<Compile Include="Devices\FIND HOMES Interfaces.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SigHelper.cs" />
|
||||
<Compile Include="SmartObjects\SubpageReferencList\SubpageReferenceList.cs" />
|
||||
|
||||
@@ -402,13 +402,16 @@ namespace PepperDash.Essentials
|
||||
/// Loads a
|
||||
/// </summary>
|
||||
/// <param name="plugin"></param>
|
||||
/// <param name="loadedAssembly"></param>
|
||||
static void LoadCustomPlugin(IPluginDeviceFactory plugin, LoadedAssembly loadedAssembly)
|
||||
{
|
||||
var passed = Global.IsRunningMinimumVersionOrHigher(plugin.MinimumEssentialsFrameworkVersion);
|
||||
|
||||
if (!passed)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", plugin.MinimumEssentialsFrameworkVersion);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"\r\n********************\r\n\tPlugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin {1}\r\n********************",
|
||||
plugin.MinimumEssentialsFrameworkVersion, loadedAssembly.Name);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,178 +1,301 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
//using SSMono.IO;
|
||||
using PepperDash.Core.WebApi.Presets;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Presets
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that represents the model behind presets display
|
||||
/// </summary>
|
||||
public class DevicePresetsModel : Device
|
||||
{
|
||||
public event EventHandler PresetsLoaded;
|
||||
/// <summary>
|
||||
/// Class that represents the model behind presets display
|
||||
/// </summary>
|
||||
public class DevicePresetsModel : Device
|
||||
{
|
||||
public delegate void PresetRecalledCallback(ISetTopBoxNumericKeypad device, string channel);
|
||||
|
||||
public int PulseTime { get; set; }
|
||||
public int DigitSpacingMS { get; set; }
|
||||
public bool PresetsAreLoaded { get; private set; }
|
||||
public delegate void PresetsSavedCallback(List<PresetChannel> presets);
|
||||
|
||||
public List<PresetChannel> PresetsList { get { return _PresetsList.ToList(); } }
|
||||
List<PresetChannel> _PresetsList;
|
||||
public int Count { get { return PresetsList != null ? PresetsList.Count : 0; } }
|
||||
private readonly CCriticalSection _fileOps = new CCriticalSection();
|
||||
private readonly bool _initSuccess;
|
||||
|
||||
public bool UseLocalImageStorage { get; set; }
|
||||
public string ImagesLocalHostPrefix { get; set; }
|
||||
public string ImagesPathPrefix { get; set; }
|
||||
public string ListPathPrefix { get; set; }
|
||||
private readonly ISetTopBoxNumericKeypad _setTopBox;
|
||||
|
||||
/// <summary>
|
||||
/// The methods on the STB device to call when dialing
|
||||
/// </summary>
|
||||
Dictionary<char, Action<bool>> DialFunctions;
|
||||
Action<bool> EnterFunction;
|
||||
/// <summary>
|
||||
/// The methods on the STB device to call when dialing
|
||||
/// </summary>
|
||||
private Dictionary<char, Action<bool>> _dialFunctions;
|
||||
|
||||
bool DialIsRunning;
|
||||
string FilePath;
|
||||
bool InitSuccess;
|
||||
//SSMono.IO.FileSystemWatcher ListWatcher;
|
||||
private bool _dialIsRunning;
|
||||
private Action<bool> _enterFunction;
|
||||
private string _filePath;
|
||||
|
||||
public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
|
||||
: base(key)
|
||||
{
|
||||
PulseTime = 150;
|
||||
DigitSpacingMS = 150;
|
||||
public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
|
||||
: this(key, fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
_setTopBox = setTopBox;
|
||||
|
||||
try
|
||||
{
|
||||
// Grab the digit functions from the device
|
||||
// If any fail, the whole thing fails peacefully
|
||||
DialFunctions = new Dictionary<char, Action<bool>>(10)
|
||||
{
|
||||
{ '1', setTopBox.Digit1 },
|
||||
{ '2', setTopBox.Digit2 },
|
||||
{ '3', setTopBox.Digit3 },
|
||||
{ '4', setTopBox.Digit4 },
|
||||
{ '5', setTopBox.Digit5 },
|
||||
{ '6', setTopBox.Digit6 },
|
||||
{ '7', setTopBox.Digit7 },
|
||||
{ '8', setTopBox.Digit8 },
|
||||
{ '9', setTopBox.Digit9 },
|
||||
{ '0', setTopBox.Digit0 },
|
||||
{ '-', setTopBox.Dash }
|
||||
};
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
|
||||
DialFunctions = null;
|
||||
return;
|
||||
}
|
||||
// Grab the digit functions from the device
|
||||
// If any fail, the whole thing fails peacefully
|
||||
_dialFunctions = new Dictionary<char, Action<bool>>(10)
|
||||
{
|
||||
{'1', setTopBox.Digit1},
|
||||
{'2', setTopBox.Digit2},
|
||||
{'3', setTopBox.Digit3},
|
||||
{'4', setTopBox.Digit4},
|
||||
{'5', setTopBox.Digit5},
|
||||
{'6', setTopBox.Digit6},
|
||||
{'7', setTopBox.Digit7},
|
||||
{'8', setTopBox.Digit8},
|
||||
{'9', setTopBox.Digit9},
|
||||
{'0', setTopBox.Digit0},
|
||||
{'-', setTopBox.Dash}
|
||||
};
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
|
||||
_dialFunctions = null;
|
||||
return;
|
||||
}
|
||||
|
||||
EnterFunction = setTopBox.KeypadEnter;
|
||||
_enterFunction = setTopBox.KeypadEnter;
|
||||
}
|
||||
|
||||
UseLocalImageStorage = true;
|
||||
public DevicePresetsModel(string key, string fileName) : base(key)
|
||||
{
|
||||
PulseTime = 150;
|
||||
DigitSpacingMs = 150;
|
||||
|
||||
ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS,0);
|
||||
ImagesPathPrefix = @"/presets/images.zip/";
|
||||
ListPathPrefix = @"/html/presets/lists/";
|
||||
UseLocalImageStorage = true;
|
||||
|
||||
SetFileName(fileName);
|
||||
ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
|
||||
ImagesPathPrefix = @"/presets/images.zip/";
|
||||
ListPathPrefix = @"/html/presets/lists/";
|
||||
|
||||
//ListWatcher = new FileSystemWatcher(@"\HTML\presets\lists");
|
||||
//ListWatcher.NotifyFilter = NotifyFilters.LastWrite;
|
||||
//ListWatcher.EnableRaisingEvents = true;
|
||||
//ListWatcher.Changed += ListWatcher_Changed;
|
||||
InitSuccess = true;
|
||||
}
|
||||
SetFileName(fileName);
|
||||
|
||||
_initSuccess = true;
|
||||
}
|
||||
|
||||
public event PresetRecalledCallback PresetRecalled;
|
||||
public event PresetsSavedCallback PresetsSaved;
|
||||
|
||||
public int PulseTime { get; set; }
|
||||
public int DigitSpacingMs { get; set; }
|
||||
public bool PresetsAreLoaded { get; private set; }
|
||||
|
||||
public List<PresetChannel> PresetsList { get; private set; }
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return PresetsList != null ? PresetsList.Count : 0; }
|
||||
}
|
||||
|
||||
public bool UseLocalImageStorage { get; set; }
|
||||
public string ImagesLocalHostPrefix { get; set; }
|
||||
public string ImagesPathPrefix { get; set; }
|
||||
public string ListPathPrefix { get; set; }
|
||||
public event EventHandler PresetsLoaded;
|
||||
|
||||
|
||||
public void SetFileName(string path)
|
||||
{
|
||||
FilePath = ListPathPrefix + path;
|
||||
LoadChannels();
|
||||
}
|
||||
public void SetFileName(string path)
|
||||
{
|
||||
_filePath = ListPathPrefix + path;
|
||||
|
||||
public void LoadChannels()
|
||||
{
|
||||
PresetsAreLoaded = false;
|
||||
try
|
||||
{
|
||||
var pl = JsonConvert.DeserializeObject<PresetsList>(Crestron.SimplSharp.CrestronIO.File.ReadToEnd(FilePath, Encoding.ASCII));
|
||||
Name = pl.Name;
|
||||
_PresetsList = pl.Channels;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this, "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}", FilePath, e.Message);
|
||||
// Just save a default empty list
|
||||
_PresetsList = new List<PresetChannel>();
|
||||
}
|
||||
PresetsAreLoaded = true;
|
||||
Debug.Console(2, this, "Setting presets file path to {0}", _filePath);
|
||||
LoadChannels();
|
||||
}
|
||||
|
||||
var handler = PresetsLoaded;
|
||||
if (handler != null)
|
||||
handler(this, EventArgs.Empty);
|
||||
}
|
||||
public void LoadChannels()
|
||||
{
|
||||
try
|
||||
{
|
||||
_fileOps.Enter();
|
||||
|
||||
public void Dial(int presetNum)
|
||||
{
|
||||
if (presetNum <= _PresetsList.Count)
|
||||
Dial(_PresetsList[presetNum - 1].Channel);
|
||||
}
|
||||
Debug.Console(2, this, "Loading presets from {0}", _filePath);
|
||||
PresetsAreLoaded = false;
|
||||
try
|
||||
{
|
||||
var pl = JsonConvert.DeserializeObject<PresetsList>(File.ReadToEnd(_filePath, Encoding.ASCII));
|
||||
Name = pl.Name;
|
||||
PresetsList = pl.Channels;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this,
|
||||
"LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}",
|
||||
_filePath, e.Message);
|
||||
// Just save a default empty list
|
||||
PresetsList = new List<PresetChannel>();
|
||||
}
|
||||
PresetsAreLoaded = true;
|
||||
|
||||
public void Dial(string chanNum)
|
||||
{
|
||||
if (DialIsRunning || !InitSuccess) return;
|
||||
if (DialFunctions == null)
|
||||
{
|
||||
Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
|
||||
return;
|
||||
}
|
||||
var handler = PresetsLoaded;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_fileOps.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
DialIsRunning = true;
|
||||
CrestronInvoke.BeginInvoke(o =>
|
||||
{
|
||||
foreach (var c in chanNum.ToCharArray())
|
||||
{
|
||||
if (DialFunctions.ContainsKey(c))
|
||||
Pulse(DialFunctions[c]);
|
||||
CrestronEnvironment.Sleep(DigitSpacingMS);
|
||||
}
|
||||
public void Dial(int presetNum)
|
||||
{
|
||||
if (presetNum <= PresetsList.Count)
|
||||
{
|
||||
Dial(PresetsList[presetNum - 1].Channel);
|
||||
}
|
||||
}
|
||||
|
||||
if (EnterFunction != null)
|
||||
Pulse(EnterFunction);
|
||||
DialIsRunning = false;
|
||||
});
|
||||
}
|
||||
public void Dial(string chanNum)
|
||||
{
|
||||
if (_dialIsRunning || !_initSuccess)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_dialFunctions == null)
|
||||
{
|
||||
Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
|
||||
return;
|
||||
}
|
||||
|
||||
void Pulse(Action<bool> act)
|
||||
{
|
||||
act(true);
|
||||
CrestronEnvironment.Sleep(PulseTime);
|
||||
act(false);
|
||||
}
|
||||
_dialIsRunning = true;
|
||||
CrestronInvoke.BeginInvoke(o =>
|
||||
{
|
||||
foreach (var c in chanNum.ToCharArray())
|
||||
{
|
||||
if (_dialFunctions.ContainsKey(c))
|
||||
{
|
||||
Pulse(_dialFunctions[c]);
|
||||
}
|
||||
CrestronEnvironment.Sleep(DigitSpacingMs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for filesystem watcher. When directory changes, this is called
|
||||
/// </summary>
|
||||
//void ListWatcher_Changed(object sender, FileSystemEventArgs e)
|
||||
//{
|
||||
// Debug.Console(1, this, "folder modified: {0}", e.FullPath);
|
||||
// if (e.FullPath.Equals(FilePath, StringComparison.OrdinalIgnoreCase))
|
||||
// {
|
||||
// Debug.Console(1, this, "File changed: {0}", e.ChangeType);
|
||||
// LoadChannels();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
if (_enterFunction != null)
|
||||
{
|
||||
Pulse(_enterFunction);
|
||||
}
|
||||
_dialIsRunning = false;
|
||||
});
|
||||
|
||||
if (_setTopBox == null) return;
|
||||
|
||||
OnPresetRecalled(_setTopBox, chanNum);
|
||||
}
|
||||
|
||||
public void Dial(int presetNum, ISetTopBoxNumericKeypad setTopBox)
|
||||
{
|
||||
if (presetNum <= PresetsList.Count)
|
||||
{
|
||||
Dial(PresetsList[presetNum - 1].Channel, setTopBox);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dial(string chanNum, ISetTopBoxNumericKeypad setTopBox)
|
||||
{
|
||||
_dialFunctions = new Dictionary<char, Action<bool>>(10)
|
||||
{
|
||||
{'1', setTopBox.Digit1},
|
||||
{'2', setTopBox.Digit2},
|
||||
{'3', setTopBox.Digit3},
|
||||
{'4', setTopBox.Digit4},
|
||||
{'5', setTopBox.Digit5},
|
||||
{'6', setTopBox.Digit6},
|
||||
{'7', setTopBox.Digit7},
|
||||
{'8', setTopBox.Digit8},
|
||||
{'9', setTopBox.Digit9},
|
||||
{'0', setTopBox.Digit0},
|
||||
{'-', setTopBox.Dash}
|
||||
};
|
||||
|
||||
_enterFunction = setTopBox.KeypadEnter;
|
||||
|
||||
OnPresetRecalled(setTopBox, chanNum);
|
||||
|
||||
Dial(chanNum);
|
||||
}
|
||||
|
||||
private void OnPresetRecalled(ISetTopBoxNumericKeypad setTopBox, string channel)
|
||||
{
|
||||
var handler = PresetRecalled;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(setTopBox, channel);
|
||||
}
|
||||
|
||||
public void UpdatePreset(int index, PresetChannel preset)
|
||||
{
|
||||
if (index >= PresetsList.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PresetsList[index] = preset;
|
||||
|
||||
SavePresets();
|
||||
|
||||
OnPresetsSaved();
|
||||
}
|
||||
|
||||
public void UpdatePresets(List<PresetChannel> presets)
|
||||
{
|
||||
PresetsList = presets;
|
||||
|
||||
SavePresets();
|
||||
|
||||
OnPresetsSaved();
|
||||
}
|
||||
|
||||
private void SavePresets()
|
||||
{
|
||||
try
|
||||
{
|
||||
_fileOps.Enter();
|
||||
var json = JsonConvert.SerializeObject(PresetsList);
|
||||
|
||||
using (var file = File.Open(_filePath, FileMode.Truncate))
|
||||
{
|
||||
file.Write(json, Encoding.UTF8);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
_fileOps.Leave();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void OnPresetsSaved()
|
||||
{
|
||||
var handler = PresetsSaved;
|
||||
|
||||
if (handler == null) return;
|
||||
|
||||
handler(PresetsList);
|
||||
}
|
||||
|
||||
private void Pulse(Action<bool> act)
|
||||
{
|
||||
act(true);
|
||||
CrestronEnvironment.Sleep(PulseTime);
|
||||
act(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,19 +10,22 @@ namespace PepperDash.Essentials.Core.Presets
|
||||
public class PresetChannel
|
||||
{
|
||||
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
[JsonProperty(Required = Required.Always,PropertyName = "name")]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
|
||||
[JsonProperty(Required = Required.Always, PropertyName = "iconUrl")]
|
||||
public string IconUrl { get; set; }
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
|
||||
[JsonProperty(Required = Required.Always, PropertyName = "channel")]
|
||||
public string Channel { get; set; }
|
||||
}
|
||||
|
||||
public class PresetsList
|
||||
{
|
||||
[JsonProperty(Required=Required.Always)]
|
||||
[JsonProperty(Required=Required.Always,PropertyName = "name")]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
|
||||
[JsonProperty(Required = Required.Always, PropertyName = "channels")]
|
||||
public List<PresetChannel> Channels { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
/// <summary>
|
||||
/// IBasicCommunication Message for IQueue
|
||||
|
||||
@@ -3,7 +3,7 @@ using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.CrestronThread;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
/// <summary>
|
||||
/// Threadsafe processing of queued items with pacing if required
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
public interface IQueue<T> : IKeyed, IDisposable where T : class
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
public interface IQueueMessage
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
/// <summary>
|
||||
/// Message class for processing strings via an IQueue
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
public sealed class StringResponseProcessor : IKeyed, IDisposable
|
||||
{
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
}
|
||||
|
||||
void _gateway_IsReadyEvent(object sender, Core.IsReadyEventArgs e)
|
||||
void _gateway_IsReadyEvent(object sender, PepperDash_Essentials_Core.IsReadyEventArgs e)
|
||||
{
|
||||
if (e.IsReady != true) return;
|
||||
_remote = GetHr1x0WirelessRemote(_config);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user