mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-11 19:44:52 +00:00
Merge pull request #1340 from PepperDash/display-bridging
Display bridging, Docs, Appdebug
This commit is contained in:
@@ -131,14 +131,14 @@ namespace PepperDash.Core
|
||||
/// <param name="key"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="port"></param>
|
||||
/// <param name="buffefSize"></param>
|
||||
public GenericUdpServer(string key, string address, int port, int buffefSize)
|
||||
/// <param name="bufferSize"></param>
|
||||
public GenericUdpServer(string key, string address, int port, int bufferSize)
|
||||
: base(key)
|
||||
{
|
||||
StreamDebugging = new CommunicationStreamDebugging(key);
|
||||
Hostname = address;
|
||||
Port = port;
|
||||
BufferSize = buffefSize;
|
||||
BufferSize = bufferSize;
|
||||
|
||||
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
||||
CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
|
||||
@@ -194,7 +194,21 @@ namespace PepperDash.Core
|
||||
{
|
||||
if (Server == null)
|
||||
{
|
||||
Server = new UDPServer();
|
||||
try
|
||||
{
|
||||
var address = IPAddress.Parse(Hostname);
|
||||
|
||||
Server = new UDPServer(address, Port, BufferSize);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.LogError("Error parsing IP Address '{ipAddress}': message: {message}", Hostname, ex.Message);
|
||||
this.LogInformation("Creating UDPServer with default buffersize");
|
||||
|
||||
Server = new UDPServer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Hostname))
|
||||
|
||||
@@ -40,20 +40,20 @@ namespace PepperDash.Core
|
||||
|
||||
private static ILogger _logger;
|
||||
|
||||
private static readonly LoggingLevelSwitch _consoleLoggingLevelSwitch;
|
||||
private static readonly LoggingLevelSwitch _consoleLogLevelSwitch;
|
||||
|
||||
private static readonly LoggingLevelSwitch _websocketLoggingLevelSwitch;
|
||||
private static readonly LoggingLevelSwitch _websocketLogLevelSwitch;
|
||||
|
||||
private static readonly LoggingLevelSwitch _errorLogLevelSwitch;
|
||||
|
||||
private static readonly LoggingLevelSwitch _fileLevelSwitch;
|
||||
private static readonly LoggingLevelSwitch _fileLogLevelSwitch;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum log level for the websocket sink.
|
||||
/// </summary>
|
||||
public static LogEventLevel WebsocketMinimumLogLevel
|
||||
{
|
||||
get { return _websocketLoggingLevelSwitch.MinimumLevel; }
|
||||
get { return _websocketLogLevelSwitch.MinimumLevel; }
|
||||
}
|
||||
|
||||
private static readonly DebugWebsocketSink _websocketSink;
|
||||
@@ -138,13 +138,13 @@ namespace PepperDash.Core
|
||||
|
||||
var defaultFileLogLevel = GetStoredLogEventLevel(FileLevelStoreKey);
|
||||
|
||||
_consoleLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultConsoleLevel);
|
||||
_consoleLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultConsoleLevel);
|
||||
|
||||
_websocketLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultWebsocketLevel);
|
||||
_websocketLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultWebsocketLevel);
|
||||
|
||||
_errorLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultErrorLogLevel);
|
||||
|
||||
_fileLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultFileLogLevel);
|
||||
_fileLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultFileLogLevel);
|
||||
|
||||
_websocketSink = new DebugWebsocketSink(new JsonFormatter(renderMessage: true));
|
||||
|
||||
@@ -162,14 +162,14 @@ namespace PepperDash.Core
|
||||
.MinimumLevel.Verbose()
|
||||
.Enrich.FromLogContext()
|
||||
.Enrich.With(new CrestronEnricher())
|
||||
.WriteTo.Sink(new DebugConsoleSink(new ExpressionTemplate("[{@t:yyyy-MM-dd HH:mm:ss.fff}][{@l:u4}][{App}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}")), levelSwitch: _consoleLoggingLevelSwitch)
|
||||
.WriteTo.Sink(_websocketSink, levelSwitch: _websocketLoggingLevelSwitch)
|
||||
.WriteTo.Sink(new DebugConsoleSink(new ExpressionTemplate("[{@t:yyyy-MM-dd HH:mm:ss.fff}][{@l:u4}][{App}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}")), levelSwitch: _consoleLogLevelSwitch)
|
||||
.WriteTo.Sink(_websocketSink, levelSwitch: _websocketLogLevelSwitch)
|
||||
.WriteTo.Sink(new DebugErrorLogSink(new ExpressionTemplate(errorLogTemplate)), levelSwitch: _errorLogLevelSwitch)
|
||||
.WriteTo.File(new RenderedCompactJsonFormatter(), logFilePath,
|
||||
rollingInterval: RollingInterval.Day,
|
||||
restrictedToMinimumLevel: LogEventLevel.Debug,
|
||||
retainedFileCountLimit: CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? 30 : 60,
|
||||
levelSwitch: _fileLevelSwitch
|
||||
levelSwitch: _fileLogLevelSwitch
|
||||
);
|
||||
|
||||
try
|
||||
@@ -237,10 +237,13 @@ namespace PepperDash.Core
|
||||
if (DoNotLoadConfigOnNextBoot)
|
||||
CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber));
|
||||
|
||||
_consoleLoggingLevelSwitch.MinimumLevelChanged += (sender, args) =>
|
||||
_errorLogLevelSwitch.MinimumLevelChanged += (sender, args) =>
|
||||
{
|
||||
LogMessage(LogEventLevel.Information, "Console debug level set to {minimumLevel}", _consoleLoggingLevelSwitch.MinimumLevel);
|
||||
LogMessage(LogEventLevel.Information, "Error log debug level set to {minimumLevel}", _errorLogLevelSwitch.MinimumLevel);
|
||||
};
|
||||
|
||||
// Set initial error log level based on platform && stored level. If appliance, use stored level, otherwise default to verbose
|
||||
SetErrorLogMinimumDebugLevel(CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? _errorLogLevelSwitch.MinimumLevel : LogEventLevel.Verbose);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -273,9 +276,9 @@ namespace PepperDash.Core
|
||||
{
|
||||
CrestronConsole.Print($"Unable to retrieve stored log level for {levelStoreKey}.\r\nError: {result}.\r\nSetting level to {LogEventLevel.Information}\r\n");
|
||||
|
||||
CrestronDataStoreStatic.SetLocalIntValue(levelStoreKey, (int)LogEventLevel.Information);
|
||||
CrestronDataStoreStatic.SetLocalIntValue(levelStoreKey, levelStoreKey == ErrorLogLevelStoreKey ? (int)LogEventLevel.Warning : (int)LogEventLevel.Information);
|
||||
|
||||
return LogEventLevel.Information;
|
||||
return levelStoreKey == ErrorLogLevelStoreKey ? LogEventLevel.Warning : LogEventLevel.Information;
|
||||
}
|
||||
|
||||
if (logLevel < 0 || logLevel > 5)
|
||||
@@ -284,6 +287,8 @@ namespace PepperDash.Core
|
||||
return LogEventLevel.Information;
|
||||
}
|
||||
|
||||
CrestronConsole.PrintLine($"Stored log level for {levelStoreKey} is {logLevel}");
|
||||
|
||||
return (LogEventLevel)logLevel;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -349,7 +354,11 @@ namespace PepperDash.Core
|
||||
if (levelString.Trim() == "?")
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(
|
||||
"Used to set the minimum level of debug messages to be printed to the console:\r\n" +
|
||||
"Used to set the minimum level of debug messages:\r\n" +
|
||||
"Usage: appdebug:P [sink] [level]\r\n" +
|
||||
" sink: console (default), errorlog, file, all\r\n" +
|
||||
" all: sets all sinks to the specified level\r\n" +
|
||||
" level: 0-5 or LogEventLevel name\r\n" +
|
||||
$"{_logLevels[0]} = 0\r\n" +
|
||||
$"{_logLevels[1]} = 1\r\n" +
|
||||
$"{_logLevels[2]} = 2\r\n" +
|
||||
@@ -361,32 +370,88 @@ namespace PepperDash.Core
|
||||
|
||||
if (string.IsNullOrEmpty(levelString.Trim()))
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("AppDebug level = {0}", _consoleLoggingLevelSwitch.MinimumLevel);
|
||||
CrestronConsole.ConsoleCommandResponse("Console log level = {0}\r\n", _consoleLogLevelSwitch.MinimumLevel);
|
||||
CrestronConsole.ConsoleCommandResponse("File log level = {0}\r\n", _fileLogLevelSwitch.MinimumLevel);
|
||||
CrestronConsole.ConsoleCommandResponse("Error log level = {0}\r\n", _errorLogLevelSwitch.MinimumLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (int.TryParse(levelString, out var levelInt))
|
||||
// Parse tokens: first token is sink (defaults to console), second token is level
|
||||
var tokens = levelString.Trim().Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
string sinkName;
|
||||
string levelToken;
|
||||
|
||||
if (tokens.Length == 1)
|
||||
{
|
||||
// Single token - assume it's a level for console sink
|
||||
sinkName = "console";
|
||||
levelToken = tokens[0];
|
||||
}
|
||||
else if (tokens.Length == 2)
|
||||
{
|
||||
// Two tokens - first is sink, second is level
|
||||
sinkName = tokens[0].ToLowerInvariant();
|
||||
levelToken = tokens[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [sink] [level]");
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the level using the same logic as before
|
||||
LogEventLevel level;
|
||||
|
||||
if (int.TryParse(levelToken, out var levelInt))
|
||||
{
|
||||
if (levelInt < 0 || levelInt > 5)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level. If using a number, value must be between 0-5");
|
||||
CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelToken} to valid log level. If using a number, value must be between 0-5");
|
||||
return;
|
||||
}
|
||||
SetDebugLevel((uint)levelInt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Enum.TryParse<LogEventLevel>(levelString, true, out var levelEnum))
|
||||
if (!_logLevels.TryGetValue((uint)levelInt, out level))
|
||||
{
|
||||
level = LogEventLevel.Information;
|
||||
CrestronConsole.ConsoleCommandResponse($"{levelInt} not valid. Setting level to {level}");
|
||||
}
|
||||
}
|
||||
else if (Enum.TryParse(levelToken, true, out level))
|
||||
{
|
||||
SetDebugLevel(levelEnum);
|
||||
// Successfully parsed as LogEventLevel enum
|
||||
}
|
||||
else
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelToken} to valid log level");
|
||||
return;
|
||||
}
|
||||
|
||||
CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level");
|
||||
// Set the level for the specified sink
|
||||
switch (sinkName)
|
||||
{
|
||||
case "console":
|
||||
SetDebugLevel(level);
|
||||
break;
|
||||
case "errorlog":
|
||||
SetErrorLogMinimumDebugLevel(level);
|
||||
break;
|
||||
case "file":
|
||||
SetFileMinimumDebugLevel(level);
|
||||
break;
|
||||
case "all":
|
||||
SetDebugLevel(level);
|
||||
SetErrorLogMinimumDebugLevel(level);
|
||||
SetFileMinimumDebugLevel(level);
|
||||
break;
|
||||
default:
|
||||
CrestronConsole.ConsoleCommandResponse($"Error: Unknown sink '{sinkName}'. Valid sinks: console, errorlog, file");
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [0-5]");
|
||||
CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [sink] [level]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,10 +481,10 @@ namespace PepperDash.Core
|
||||
/// </summary>
|
||||
public static void SetDebugLevel(LogEventLevel level)
|
||||
{
|
||||
_consoleLoggingLevelSwitch.MinimumLevel = level;
|
||||
_consoleLogLevelSwitch.MinimumLevel = level;
|
||||
|
||||
CrestronConsole.ConsoleCommandResponse("[Application {0}], Debug level set to {1}\r\n",
|
||||
InitialParametersClass.ApplicationNumber, _consoleLoggingLevelSwitch.MinimumLevel);
|
||||
CrestronConsole.ConsoleCommandResponse("[Application {0}] Debug level set to {1}\r\n",
|
||||
InitialParametersClass.ApplicationNumber, _consoleLogLevelSwitch.MinimumLevel);
|
||||
|
||||
CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}");
|
||||
|
||||
@@ -436,14 +501,14 @@ namespace PepperDash.Core
|
||||
/// </summary>
|
||||
public static void SetWebSocketMinimumDebugLevel(LogEventLevel level)
|
||||
{
|
||||
_websocketLoggingLevelSwitch.MinimumLevel = level;
|
||||
_websocketLogLevelSwitch.MinimumLevel = level;
|
||||
|
||||
var err = CrestronDataStoreStatic.SetLocalUintValue(WebSocketLevelStoreKey, (uint)level);
|
||||
|
||||
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||
LogMessage(LogEventLevel.Information, "Error saving websocket debug level setting: {erro}", err);
|
||||
|
||||
LogMessage(LogEventLevel.Information, "Websocket debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
|
||||
LogMessage(LogEventLevel.Information, "Websocket debug level set to {0}", _websocketLogLevelSwitch.MinimumLevel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -453,12 +518,17 @@ namespace PepperDash.Core
|
||||
{
|
||||
_errorLogLevelSwitch.MinimumLevel = level;
|
||||
|
||||
var err = CrestronDataStoreStatic.SetLocalUintValue(ErrorLogLevelStoreKey, (uint)level);
|
||||
CrestronConsole.ConsoleCommandResponse("[Application {0}] Error log level set to {1}\r\n",
|
||||
InitialParametersClass.ApplicationNumber, _errorLogLevelSwitch.MinimumLevel);
|
||||
|
||||
CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}");
|
||||
|
||||
var err = CrestronDataStoreStatic.SetLocalIntValue(ErrorLogLevelStoreKey, (int)level);
|
||||
|
||||
CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}");
|
||||
|
||||
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||
LogMessage(LogEventLevel.Information, "Error saving Error Log debug level setting: {error}", err);
|
||||
|
||||
LogMessage(LogEventLevel.Information, "Error log debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
|
||||
CrestronConsole.PrintLine($"Error saving error log debug level setting: {err}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -466,14 +536,19 @@ namespace PepperDash.Core
|
||||
/// </summary>
|
||||
public static void SetFileMinimumDebugLevel(LogEventLevel level)
|
||||
{
|
||||
_errorLogLevelSwitch.MinimumLevel = level;
|
||||
_fileLogLevelSwitch.MinimumLevel = level;
|
||||
|
||||
var err = CrestronDataStoreStatic.SetLocalUintValue(ErrorLogLevelStoreKey, (uint)level);
|
||||
CrestronConsole.ConsoleCommandResponse("[Application {0}] File log level set to {1}\r\n",
|
||||
InitialParametersClass.ApplicationNumber, _fileLogLevelSwitch.MinimumLevel);
|
||||
|
||||
CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}");
|
||||
|
||||
var err = CrestronDataStoreStatic.SetLocalIntValue(FileLevelStoreKey, (int)level);
|
||||
|
||||
CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}");
|
||||
|
||||
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||
LogMessage(LogEventLevel.Information, "Error saving File debug level setting: {error}", err);
|
||||
|
||||
LogMessage(LogEventLevel.Information, "File debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
|
||||
CrestronConsole.PrintLine($"Error saving file debug level setting: {err}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
@@ -17,48 +13,68 @@ namespace PepperDash.Essentials.Devices.Common
|
||||
/// </summary>
|
||||
public class GenericAudioOut : EssentialsDevice, IRoutingSink
|
||||
{
|
||||
public RoutingInputPort CurrentInputPort => AnyAudioIn;
|
||||
/// <summary>
|
||||
/// Gets the current input port
|
||||
/// </summary>
|
||||
public RoutingInputPort CurrentInputPort => AnyAudioIn;
|
||||
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
/// <summary>
|
||||
/// Event fired when the current source changes
|
||||
/// </summary>
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
/// <summary>
|
||||
/// Gets or sets the current source info key
|
||||
/// </summary>
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the current source info
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
var handler = CurrentSourceChange;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the AnyAudioIn
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the AnyAudioIn
|
||||
/// </summary>
|
||||
public RoutingInputPort AnyAudioIn { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for GenericAudioOut
|
||||
/// </summary>
|
||||
/// <param name="key">Device key</param>
|
||||
/// <param name="name">Device name</param>
|
||||
public GenericAudioOut(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
AnyAudioIn = new RoutingInputPort(RoutingPortNames.AnyAudioIn, eRoutingSignalType.Audio,
|
||||
AnyAudioIn = new RoutingInputPort(RoutingPortNames.AnyAudioIn, eRoutingSignalType.Audio,
|
||||
eRoutingPortConnectionType.LineAudio, null, this);
|
||||
}
|
||||
|
||||
#region IRoutingInputs Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of input ports
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts
|
||||
{
|
||||
get { return new RoutingPortCollection<RoutingInputPort> { AnyAudioIn }; }
|
||||
@@ -68,23 +84,32 @@ namespace PepperDash.Essentials.Devices.Common
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a GenericAudioOutWithVolume
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Represents a GenericAudioOutWithVolume
|
||||
/// </summary>
|
||||
public class GenericAudioOutWithVolume : GenericAudioOut, IHasVolumeDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the volume device key
|
||||
/// </summary>
|
||||
public string VolumeDeviceKey { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets the volume zone
|
||||
/// </summary>
|
||||
public uint VolumeZone { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the volume device
|
||||
/// </summary>
|
||||
public IBasicVolumeControls VolumeDevice
|
||||
{
|
||||
{
|
||||
get
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(VolumeDeviceKey);
|
||||
if (dev is IAudioZones)
|
||||
return (dev as IAudioZones).Zone[VolumeZone];
|
||||
else return dev as IBasicVolumeControls;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -103,24 +128,30 @@ namespace PepperDash.Essentials.Devices.Common
|
||||
|
||||
}
|
||||
|
||||
public class GenericAudioOutWithVolumeFactory : EssentialsDeviceFactory<GenericAudioOutWithVolume>
|
||||
{
|
||||
public GenericAudioOutWithVolumeFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "genericaudiooutwithvolume" };
|
||||
}
|
||||
/// <summary>
|
||||
/// Factory for creating GenericAudioOutWithVolume devices
|
||||
/// </summary>
|
||||
public class GenericAudioOutWithVolumeFactory : EssentialsDeviceFactory<GenericAudioOutWithVolume>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for GenericAudioOutWithVolumeFactory
|
||||
/// </summary>
|
||||
public GenericAudioOutWithVolumeFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "genericaudiooutwithvolume" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new GenericAudioOutWithVolumeFactory Device");
|
||||
var zone = dc.Properties.Value<uint>("zone");
|
||||
return new GenericAudioOutWithVolume(dc.Key, dc.Name,
|
||||
dc.Properties.Value<string>("volumeDeviceKey"), zone);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new GenericAudioOutWithVolumeFactory Device");
|
||||
var zone = dc.Properties.Value<uint>("zone");
|
||||
return new GenericAudioOutWithVolume(dc.Key, dc.Name,
|
||||
dc.Properties.Value<string>("volumeDeviceKey"), zone);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract base class for audio codec devices
|
||||
/// </summary>
|
||||
public abstract class AudioCodecBase : EssentialsDevice, IHasDialer, IUsageTracking, IAudioCodecInfo
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when call status changes
|
||||
/// </summary>
|
||||
public event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
|
||||
|
||||
/// <summary>
|
||||
@@ -52,6 +54,11 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
/// </summary>
|
||||
public List<CodecActiveCallItem> ActiveCalls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for AudioCodecBase
|
||||
/// </summary>
|
||||
/// <param name="key">Device key</param>
|
||||
/// <param name="name">Device name</param>
|
||||
public AudioCodecBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
@@ -70,11 +77,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Handles call status change events
|
||||
/// </summary>
|
||||
/// <param name="previousStatus"></param>
|
||||
/// <param name="newStatus"></param>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="item">The call item that changed status</param>
|
||||
protected void OnCallStatusChange(CodecActiveCallItem item)
|
||||
{
|
||||
var handler = CallStatusChange;
|
||||
@@ -92,16 +97,22 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
|
||||
#region IHasDialer Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void Dial(string number);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void EndCall(CodecActiveCallItem activeCall);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void EndAllCalls();
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void AcceptCall(CodecActiveCallItem item);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void RejectCall(CodecActiveCallItem item);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void SendDtmf(string digit);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a common set of data about a codec
|
||||
/// </summary>
|
||||
public interface IAudioCodecInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the codec information
|
||||
/// </summary>
|
||||
AudioCodecInfo CodecInfo { get; }
|
||||
}
|
||||
|
||||
@@ -19,6 +16,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
/// </summary>
|
||||
public abstract class AudioCodecInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the phone number
|
||||
/// </summary>
|
||||
public abstract string PhoneNumber { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// For rooms that have audio codec
|
||||
/// </summary>
|
||||
public interface IHasAudioCodec:IHasInCallFeedback
|
||||
public interface IHasAudioCodec : IHasInCallFeedback
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the audio codec device
|
||||
/// </summary>
|
||||
AudioCodecBase AudioCodec { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Make this more specific
|
||||
/// </summary>
|
||||
//List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem> ActiveCalls { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
@@ -17,6 +13,12 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
/// </summary>
|
||||
public class MockAC : AudioCodecBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for MockAC
|
||||
/// </summary>
|
||||
/// <param name="key">Device key</param>
|
||||
/// <param name="name">Device name</param>
|
||||
/// <param name="props">MockAC properties configuration</param>
|
||||
public MockAC(string key, string name, MockAcPropertiesConfig props)
|
||||
: base(key, name)
|
||||
{
|
||||
@@ -109,13 +111,10 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "BEEP BOOP SendDTMF: {0}", s);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <summary>
|
||||
/// TestIncomingAudioCall method
|
||||
/// </summary>
|
||||
/// <param name="number">Phone number to call from</param>
|
||||
public void TestIncomingAudioCall(string number)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "TestIncomingAudioCall from {0}", number);
|
||||
@@ -133,6 +132,7 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
{
|
||||
string _phoneNumber;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string PhoneNumber
|
||||
{
|
||||
get
|
||||
@@ -151,6 +151,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
/// </summary>
|
||||
public class MockACFactory : EssentialsDeviceFactory<MockAC>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for MockACFactory
|
||||
/// </summary>
|
||||
public MockACFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "mockac" };
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
{
|
||||
@@ -15,10 +7,10 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
/// </summary>
|
||||
public class MockAcPropertiesConfig
|
||||
{
|
||||
[JsonProperty("phoneNumber")]
|
||||
/// <summary>
|
||||
/// Gets or sets the PhoneNumber
|
||||
/// </summary>
|
||||
[JsonProperty("phoneNumber")]
|
||||
public string PhoneNumber { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -3,20 +3,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using System.Reflection;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
@@ -26,31 +20,52 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
/// </summary>
|
||||
public enum eCameraCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// No camera capabilities
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// Camera supports pan movement
|
||||
/// </summary>
|
||||
Pan = 1,
|
||||
Tilt = 2,
|
||||
/// <summary>
|
||||
/// Camera supports tilt movement
|
||||
/// </summary>
|
||||
Tilt = 2,
|
||||
/// <summary>
|
||||
/// Camera supports zoom functionality
|
||||
/// </summary>
|
||||
Zoom = 4,
|
||||
/// <summary>
|
||||
/// Camera supports focus adjustment
|
||||
/// </summary>
|
||||
Focus = 8
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract base class for camera devices that provides common camera functionality and capabilities
|
||||
/// </summary>
|
||||
public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs
|
||||
{
|
||||
[JsonProperty("controlMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ControlMode
|
||||
/// </summary>
|
||||
[JsonProperty("controlMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public eCameraControlMode ControlMode { get; protected set; }
|
||||
|
||||
#region IRoutingOutputs Members
|
||||
|
||||
[JsonIgnore]
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputPorts
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; protected set; }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this camera supports pan movement
|
||||
/// </summary>
|
||||
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanPan
|
||||
{
|
||||
@@ -59,6 +74,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
return (Capabilities & eCameraCapabilities.Pan) == eCameraCapabilities.Pan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this camera supports tilt movement
|
||||
/// </summary>
|
||||
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanTilt
|
||||
{
|
||||
@@ -67,6 +86,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
return (Capabilities & eCameraCapabilities.Tilt) == eCameraCapabilities.Tilt;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this camera supports zoom functionality
|
||||
/// </summary>
|
||||
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanZoom
|
||||
{
|
||||
@@ -75,6 +98,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
return (Capabilities & eCameraCapabilities.Zoom) == eCameraCapabilities.Zoom;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this camera supports focus adjustment
|
||||
/// </summary>
|
||||
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanFocus
|
||||
{
|
||||
@@ -84,23 +111,42 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
}
|
||||
}
|
||||
|
||||
// A bitmasked value to indicate the movement capabilites of this camera
|
||||
/// <summary>
|
||||
/// Gets or sets a bitmasked value to indicate the movement capabilities of this camera
|
||||
/// </summary>
|
||||
protected eCameraCapabilities Capabilities { get; set; }
|
||||
|
||||
protected CameraBase(DeviceConfig config) : base(config)
|
||||
{
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
|
||||
ControlMode = eCameraControlMode.Manual;
|
||||
|
||||
}
|
||||
|
||||
protected CameraBase(string key, string name) :
|
||||
this (new DeviceConfig{Name = name, Key = key})
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CameraBase class with the specified device configuration
|
||||
/// </summary>
|
||||
/// <param name="config">The device configuration</param>
|
||||
protected CameraBase(DeviceConfig config) : base(config)
|
||||
{
|
||||
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
|
||||
ControlMode = eCameraControlMode.Manual;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CameraBase class with the specified key and name
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this camera device</param>
|
||||
/// <param name="name">The friendly name for this camera device</param>
|
||||
protected CameraBase(string key, string name) :
|
||||
this(new DeviceConfig { Name = name, Key = key })
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Links the camera device to the API bridge for control and feedback
|
||||
/// </summary>
|
||||
/// <param name="cameraDevice">The camera device to link</param>
|
||||
/// <param name="trilist">The trilist for communication</param>
|
||||
/// <param name="joinStart">The starting join number for the camera controls</param>
|
||||
/// <param name="joinMapKey">The join map key for custom join mappings</param>
|
||||
/// <param name="bridge">The EiscApiAdvanced bridge for advanced join mapping</param>
|
||||
protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||
EiscApiAdvanced bridge)
|
||||
{
|
||||
@@ -240,13 +286,13 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
int tempNum = i;
|
||||
|
||||
trilist.SetSigTrueAction((ushort) (joinMap.PresetRecallStart.JoinNumber + tempNum), () =>
|
||||
trilist.SetSigTrueAction((ushort)(joinMap.PresetRecallStart.JoinNumber + tempNum), () =>
|
||||
{
|
||||
presetsCamera.PresetSelect(tempNum);
|
||||
});
|
||||
trilist.SetSigTrueAction((ushort) (joinMap.PresetSaveStart.JoinNumber + tempNum), () =>
|
||||
trilist.SetSigTrueAction((ushort)(joinMap.PresetSaveStart.JoinNumber + tempNum), () =>
|
||||
{
|
||||
var label = trilist.GetString((ushort) (joinMap.PresetLabelStart.JoinNumber + tempNum));
|
||||
var label = trilist.GetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum));
|
||||
|
||||
presetsCamera.PresetStore(tempNum, label);
|
||||
});
|
||||
@@ -277,7 +323,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -285,6 +331,13 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
/// </summary>
|
||||
public class CameraPreset : PresetBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CameraPreset class
|
||||
/// </summary>
|
||||
/// <param name="id">The preset ID</param>
|
||||
/// <param name="description">The preset description</param>
|
||||
/// <param name="isDefined">Whether the preset is defined</param>
|
||||
/// <param name="isDefinable">Whether the preset can be defined</param>
|
||||
public CameraPreset(int id, string description, bool isDefined, bool isDefinable)
|
||||
: base(id, description, isDefined, isDefinable)
|
||||
{
|
||||
@@ -293,37 +346,37 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a CameraPropertiesConfig
|
||||
/// </summary>
|
||||
public class CameraPropertiesConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the CommunicationMonitorProperties
|
||||
/// </summary>
|
||||
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
|
||||
/// <summary>
|
||||
/// Represents a CameraPropertiesConfig
|
||||
/// </summary>
|
||||
public class CameraPropertiesConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the CommunicationMonitorProperties
|
||||
/// </summary>
|
||||
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Control
|
||||
/// </summary>
|
||||
public ControlPropertiesConfig Control { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Control
|
||||
/// </summary>
|
||||
public ControlPropertiesConfig Control { get; set; }
|
||||
|
||||
[JsonProperty("supportsAutoMode")]
|
||||
/// <summary>
|
||||
/// Gets or sets the SupportsAutoMode
|
||||
/// </summary>
|
||||
[JsonProperty("supportsAutoMode")]
|
||||
public bool SupportsAutoMode { get; set; }
|
||||
|
||||
[JsonProperty("supportsOffMode")]
|
||||
/// <summary>
|
||||
/// Gets or sets the SupportsOffMode
|
||||
/// </summary>
|
||||
[JsonProperty("supportsOffMode")]
|
||||
public bool SupportsOffMode { get; set; }
|
||||
|
||||
[JsonProperty("presets")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Presets
|
||||
/// </summary>
|
||||
[JsonProperty("presets")]
|
||||
public List<CameraPreset> Presets { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,326 +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.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum for camera control modes
|
||||
/// </summary>
|
||||
public enum eCameraControlMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Manual control mode, where the camera is controlled directly by the user or system
|
||||
/// </summary>
|
||||
Manual = 0,
|
||||
/// <summary>
|
||||
/// Off control mode, where the camera is turned off or disabled
|
||||
/// </summary>
|
||||
Off,
|
||||
/// <summary>
|
||||
/// Auto control mode, where the camera automatically adjusts settings based on the environment or conditions
|
||||
/// </summary>
|
||||
Auto
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Interface for devices that have cameras
|
||||
/// </summary>
|
||||
public interface IHasCameras : IKeyName
|
||||
{
|
||||
/// <summary>
|
||||
/// Event that is raised when a camera is selected
|
||||
/// </summary>
|
||||
event EventHandler<CameraSelectedEventArgs> CameraSelected;
|
||||
|
||||
/// <summary>
|
||||
/// List of cameras on the device. This should be a list of CameraBase objects
|
||||
/// </summary>
|
||||
List<CameraBase> Cameras { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The currently selected camera. This should be a CameraBase object
|
||||
/// </summary>
|
||||
CameraBase SelectedCamera { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Feedback that indicates the currently selected camera
|
||||
/// </summary>
|
||||
StringFeedback SelectedCameraFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Selects a camera from the list of available cameras based on the provided key.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier or name of the camera to select.</param>
|
||||
void SelectCamera(string key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCodecCameras
|
||||
/// </summary>
|
||||
public interface IHasCodecCameras : IHasCameras, IHasFarEndCameraControl
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To be implmented on codecs that can disable their camera(s) to blank the near end video
|
||||
/// </summary>
|
||||
public interface IHasCameraOff
|
||||
{
|
||||
/// <summary>
|
||||
/// Feedback that indicates whether the camera is off
|
||||
/// </summary>
|
||||
BoolFeedback CameraIsOffFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Turns the camera off, blanking the near end video
|
||||
/// </summary>
|
||||
void CameraOff();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the ability to mute and unmute camera video
|
||||
/// </summary>
|
||||
public interface IHasCameraMute
|
||||
{
|
||||
/// <summary>
|
||||
/// Feedback that indicates whether the camera is muted
|
||||
/// </summary>
|
||||
BoolFeedback CameraIsMutedFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Mutes the camera video, preventing it from being sent to the far end
|
||||
/// </summary>
|
||||
void CameraMuteOn();
|
||||
|
||||
/// <summary>
|
||||
/// Unmutes the camera video, allowing it to be sent to the far end
|
||||
/// </summary>
|
||||
void CameraMuteOff();
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the camera mute state. If the camera is muted, it will be unmuted, and vice versa.
|
||||
/// </summary>
|
||||
void CameraMuteToggle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for devices that can mute and unmute their camera video, with an event for unmute requests
|
||||
/// </summary>
|
||||
public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute
|
||||
{
|
||||
/// <summary>
|
||||
/// Event that is raised when a video unmute is requested, typically by the far end
|
||||
/// </summary>
|
||||
event EventHandler VideoUnmuteRequested;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event arguments for the CameraSelected event
|
||||
/// </summary>
|
||||
public class CameraSelectedEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the SelectedCamera
|
||||
/// </summary>
|
||||
public CameraBase SelectedCamera { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for CameraSelectedEventArgs
|
||||
/// </summary>
|
||||
/// <param name="camera"></param>
|
||||
public CameraSelectedEventArgs(CameraBase camera)
|
||||
{
|
||||
SelectedCamera = camera;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for devices that have a far end camera control
|
||||
/// </summary>
|
||||
public interface IHasFarEndCameraControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the far end camera, which is typically a CameraBase object that represents the camera at the far end of a call
|
||||
/// </summary>
|
||||
CameraBase FarEndCamera { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Feedback that indicates whether the far end camera is being controlled
|
||||
/// </summary>
|
||||
BoolFeedback ControllingFarEndCameraFeedback { get; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IAmFarEndCamera
|
||||
/// </summary>
|
||||
public interface IAmFarEndCamera
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for devices that have camera controls
|
||||
/// </summary>
|
||||
public interface IHasCameraControls
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCameraPtzControl
|
||||
/// </summary>
|
||||
public interface IHasCameraPtzControl : IHasCameraPanControl, IHasCameraTiltControl, IHasCameraZoomControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Resets the camera position
|
||||
/// </summary>
|
||||
void PositionHome();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for camera pan control
|
||||
/// </summary>
|
||||
public interface IHasCameraPanControl : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Pans the camera left
|
||||
/// </summary>
|
||||
void PanLeft();
|
||||
|
||||
/// <summary>
|
||||
/// Pans the camera right
|
||||
/// </summary>
|
||||
void PanRight();
|
||||
|
||||
/// <summary>
|
||||
/// Stops the camera pan movement
|
||||
/// </summary>
|
||||
void PanStop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCameraTiltControl
|
||||
/// </summary>
|
||||
public interface IHasCameraTiltControl : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Tilts the camera down
|
||||
/// </summary>
|
||||
void TiltDown();
|
||||
|
||||
/// <summary>
|
||||
/// Tilts the camera up
|
||||
/// </summary>
|
||||
void TiltUp();
|
||||
|
||||
/// <summary>
|
||||
/// Stops the camera tilt movement
|
||||
/// </summary>
|
||||
void TiltStop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCameraZoomControl
|
||||
/// </summary>
|
||||
public interface IHasCameraZoomControl : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Zooms the camera in
|
||||
/// </summary>
|
||||
void ZoomIn();
|
||||
|
||||
/// <summary>
|
||||
/// Zooms the camera out
|
||||
/// </summary>
|
||||
void ZoomOut();
|
||||
|
||||
/// <summary>
|
||||
/// Stops the camera zoom movement
|
||||
/// </summary>
|
||||
void ZoomStop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCameraFocusControl
|
||||
/// </summary>
|
||||
public interface IHasCameraFocusControl : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Focuses the camera near
|
||||
/// </summary>
|
||||
void FocusNear();
|
||||
|
||||
/// <summary>
|
||||
/// Focuses the camera far
|
||||
/// </summary>
|
||||
void FocusFar();
|
||||
|
||||
/// <summary>
|
||||
/// Stops the camera focus movement
|
||||
/// </summary>
|
||||
void FocusStop();
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the camera's auto focus functionality, if available.
|
||||
/// </summary>
|
||||
void TriggerAutoFocus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for devices that have auto focus mode control
|
||||
/// </summary>
|
||||
public interface IHasAutoFocusMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the focus mode to auto or manual, or toggles between them.
|
||||
/// </summary>
|
||||
void SetFocusModeAuto();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the focus mode to manual, allowing for manual focus adjustments.
|
||||
/// </summary>
|
||||
void SetFocusModeManual();
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the focus mode between auto and manual.
|
||||
/// </summary>
|
||||
void ToggleFocusMode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for devices that have camera auto mode control
|
||||
/// </summary>
|
||||
public interface IHasCameraAutoMode : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Enables or disables the camera's auto mode, which may include automatic adjustments for focus, exposure, and other settings.
|
||||
/// </summary>
|
||||
void CameraAutoModeOn();
|
||||
|
||||
/// <summary>
|
||||
/// Disables the camera's auto mode, allowing for manual control of camera settings.
|
||||
/// </summary>
|
||||
void CameraAutoModeOff();
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the camera's auto mode state. If the camera is in auto mode, it will switch to manual mode, and vice versa.
|
||||
/// </summary>
|
||||
void CameraAutoModeToggle();
|
||||
|
||||
/// <summary>
|
||||
/// Feedback that indicates whether the camera's auto mode is currently enabled.
|
||||
/// </summary>
|
||||
BoolFeedback CameraAutoModeIsOnFeedback { get; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -3,38 +3,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Reflection;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a CameraVisca
|
||||
/// </summary>
|
||||
public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IHasPowerControlWithFeedback, IBridgeAdvanced, IHasCameraFocusControl, IHasAutoFocusMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a CameraVisca
|
||||
/// </summary>
|
||||
public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IHasPowerControlWithFeedback, IBridgeAdvanced, IHasCameraFocusControl, IHasAutoFocusMode
|
||||
{
|
||||
private readonly CameraViscaPropertiesConfig PropertiesConfig;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Communication
|
||||
/// </summary>
|
||||
public IBasicCommunication Communication { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Communication
|
||||
/// </summary>
|
||||
public IBasicCommunication Communication { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CommunicationMonitor
|
||||
/// </summary>
|
||||
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the CommunicationMonitor
|
||||
/// </summary>
|
||||
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to store the actions to parse inquiry responses as the inquiries are sent
|
||||
@@ -45,20 +40,41 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
/// Camera ID (Default 1)
|
||||
/// </summary>
|
||||
public byte ID = 0x01;
|
||||
|
||||
/// <summary>
|
||||
/// Response ID used for VISCA communication
|
||||
/// </summary>
|
||||
public byte ResponseID;
|
||||
|
||||
/// <summary>
|
||||
/// Slow speed value for pan movement
|
||||
/// </summary>
|
||||
public byte PanSpeedSlow = 0x10;
|
||||
|
||||
public byte PanSpeedSlow = 0x10;
|
||||
public byte TiltSpeedSlow = 0x10;
|
||||
/// <summary>
|
||||
/// Slow speed value for tilt movement
|
||||
/// </summary>
|
||||
public byte TiltSpeedSlow = 0x10;
|
||||
|
||||
/// <summary>
|
||||
/// Fast speed value for pan movement
|
||||
/// </summary>
|
||||
public byte PanSpeedFast = 0x13;
|
||||
|
||||
/// <summary>
|
||||
/// Fast speed value for tilt movement
|
||||
/// </summary>
|
||||
public byte TiltSpeedFast = 0x13;
|
||||
|
||||
// private bool IsMoving;
|
||||
private bool IsZooming;
|
||||
private bool IsZooming;
|
||||
|
||||
bool _powerIsOn;
|
||||
public bool PowerIsOn
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the camera power is on
|
||||
/// </summary>
|
||||
public bool PowerIsOn
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -87,12 +103,23 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
|
||||
long FastSpeedHoldTimeMs = 2000;
|
||||
|
||||
byte[] IncomingBuffer = new byte[] { };
|
||||
public BoolFeedback PowerIsOnFeedback { get; private set; }
|
||||
byte[] IncomingBuffer = new byte[] { };
|
||||
|
||||
/// <summary>
|
||||
/// Feedback indicating whether the camera power is on
|
||||
/// </summary>
|
||||
public BoolFeedback PowerIsOnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CameraVisca class
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this camera device</param>
|
||||
/// <param name="name">The friendly name for this camera device</param>
|
||||
/// <param name="comm">The communication interface for VISCA protocol</param>
|
||||
/// <param name="props">The camera properties configuration</param>
|
||||
public CameraVisca(string key, string name, IBasicCommunication comm, CameraViscaPropertiesConfig props) :
|
||||
base(key, name)
|
||||
{
|
||||
base(key, name)
|
||||
{
|
||||
InquiryResponseQueue = new CrestronQueue<Action<byte[]>>(15);
|
||||
|
||||
Presets = props.Presets;
|
||||
@@ -107,8 +134,8 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
OutputPorts.Add(new RoutingOutputPort("videoOut", eRoutingSignalType.Video, eRoutingPortConnectionType.None, null, this, true));
|
||||
|
||||
// Default to all capabilties
|
||||
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom | eCameraCapabilities.Focus;
|
||||
|
||||
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom | eCameraCapabilities.Focus;
|
||||
|
||||
Communication = comm;
|
||||
if (comm is ISocketStatus socket)
|
||||
{
|
||||
@@ -121,19 +148,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
}
|
||||
|
||||
Communication.BytesReceived += new EventHandler<GenericCommMethodReceiveBytesArgs>(Communication_BytesReceived);
|
||||
PowerIsOnFeedback = new BoolFeedback(() => { return PowerIsOn; });
|
||||
CameraIsOffFeedback = new BoolFeedback(() => { return !PowerIsOn; });
|
||||
PowerIsOnFeedback = new BoolFeedback("powerIsOn", () => { return PowerIsOn; });
|
||||
CameraIsOffFeedback = new BoolFeedback("cameraIsOff", () => { return !PowerIsOn; });
|
||||
|
||||
if (props.CommunicationMonitorProperties != null)
|
||||
{
|
||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
|
||||
}
|
||||
else
|
||||
{
|
||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 20000, 120000, 300000, "\x81\x09\x04\x00\xFF");
|
||||
}
|
||||
DeviceManager.AddDevice(CommunicationMonitor);
|
||||
}
|
||||
if (props.CommunicationMonitorProperties != null)
|
||||
{
|
||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
|
||||
}
|
||||
else
|
||||
{
|
||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 20000, 120000, 300000, "\x81\x09\x04\x00\xFF");
|
||||
}
|
||||
DeviceManager.AddDevice(CommunicationMonitor);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -165,57 +192,57 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CustomActivate method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
Communication.Connect();
|
||||
|
||||
|
||||
CommunicationMonitor.StatusChange += (o, a) => { Debug.LogMessage(LogEventLevel.Verbose, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
|
||||
CommunicationMonitor.Start();
|
||||
/// <summary>
|
||||
/// CustomActivate method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
Communication.Connect();
|
||||
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
return true;
|
||||
}
|
||||
CommunicationMonitor.StatusChange += (o, a) => { Debug.LogMessage(LogEventLevel.Verbose, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
|
||||
CommunicationMonitor.Start();
|
||||
|
||||
/// <summary>
|
||||
/// LinkToApi method
|
||||
/// </summary>
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
|
||||
void Socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString());
|
||||
CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (e.Client.IsConnected)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/// <summary>
|
||||
/// LinkToApi method
|
||||
/// </summary>
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString());
|
||||
|
||||
void SendBytes(byte[] b)
|
||||
{
|
||||
|
||||
if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Sending:{0}", ComTextHelper.GetEscapedText(b));
|
||||
if (e.Client.IsConnected)
|
||||
{
|
||||
|
||||
Communication.SendBytes(b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SendBytes(byte[] b)
|
||||
{
|
||||
|
||||
if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Sending:{0}", ComTextHelper.GetEscapedText(b));
|
||||
|
||||
Communication.SendBytes(b);
|
||||
}
|
||||
|
||||
void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
|
||||
{
|
||||
var newBytes = new byte[IncomingBuffer.Length + e.Bytes.Length];
|
||||
|
||||
try
|
||||
@@ -355,10 +382,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
/// <summary>
|
||||
/// Sends a pan/tilt command. If the command is not for fastSpeed then it starts a timer to initiate fast speed.
|
||||
/// </summary>
|
||||
/// <param name="cmd"></param>
|
||||
/// <param name="fastSpeed"></param>
|
||||
private void SendPanTiltCommand (byte[] cmd, bool fastSpeedEnabled)
|
||||
{
|
||||
/// <param name="cmd">The VISCA command to send</param>
|
||||
/// <param name="fastSpeedEnabled">Whether fast speed is enabled for this command</param>
|
||||
private void SendPanTiltCommand(byte[] cmd, bool fastSpeedEnabled)
|
||||
{
|
||||
SendBytes(GetPanTiltCommand(cmd, fastSpeedEnabled));
|
||||
|
||||
if (!fastSpeedEnabled)
|
||||
@@ -372,7 +399,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
SpeedTimer = new CTimer((o) => SendPanTiltCommand(GetPanTiltCommand(cmd, true), true), FastSpeedHoldTimeMs);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void StopSpeedTimer()
|
||||
{
|
||||
@@ -381,7 +408,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
SpeedTimer.Stop();
|
||||
SpeedTimer.Dispose();
|
||||
SpeedTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -424,14 +451,14 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
InquiryResponseQueue.Enqueue(HandlePowerResponse);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PowerOn method
|
||||
/// </summary>
|
||||
public void PowerOn()
|
||||
{
|
||||
SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x02, 0xFF });
|
||||
/// <summary>
|
||||
/// PowerOn method
|
||||
/// </summary>
|
||||
public void PowerOn()
|
||||
{
|
||||
SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x02, 0xFF });
|
||||
SendPowerQuery();
|
||||
}
|
||||
}
|
||||
|
||||
void HandlePowerResponse(byte[] response)
|
||||
{
|
||||
@@ -450,12 +477,12 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PowerOff method
|
||||
/// </summary>
|
||||
public void PowerOff()
|
||||
{
|
||||
SendBytes(new byte[] {ID, 0x01, 0x04, 0x00, 0x03, 0xFF});
|
||||
/// <summary>
|
||||
/// PowerOff method
|
||||
/// </summary>
|
||||
public void PowerOff()
|
||||
{
|
||||
SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x03, 0xFF });
|
||||
SendPowerQuery();
|
||||
}
|
||||
|
||||
@@ -470,22 +497,22 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
PowerOn();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PanLeft method
|
||||
/// </summary>
|
||||
public void PanLeft()
|
||||
{
|
||||
SendPanTiltCommand(new byte[] {0x01, 0x03}, false);
|
||||
// IsMoving = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// PanRight method
|
||||
/// </summary>
|
||||
public void PanRight()
|
||||
{
|
||||
/// <summary>
|
||||
/// PanLeft method
|
||||
/// </summary>
|
||||
public void PanLeft()
|
||||
{
|
||||
SendPanTiltCommand(new byte[] { 0x01, 0x03 }, false);
|
||||
// IsMoving = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// PanRight method
|
||||
/// </summary>
|
||||
public void PanRight()
|
||||
{
|
||||
SendPanTiltCommand(new byte[] { 0x02, 0x03 }, false);
|
||||
// IsMoving = true;
|
||||
}
|
||||
// IsMoving = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// PanStop method
|
||||
/// </summary>
|
||||
@@ -493,22 +520,22 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
/// <summary>
|
||||
/// TiltDown method
|
||||
/// </summary>
|
||||
public void TiltDown()
|
||||
{
|
||||
/// <summary>
|
||||
/// TiltDown method
|
||||
/// </summary>
|
||||
public void TiltDown()
|
||||
{
|
||||
SendPanTiltCommand(new byte[] { 0x03, 0x02 }, false);
|
||||
// IsMoving = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// TiltUp method
|
||||
/// </summary>
|
||||
public void TiltUp()
|
||||
{
|
||||
// IsMoving = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// TiltUp method
|
||||
/// </summary>
|
||||
public void TiltUp()
|
||||
{
|
||||
SendPanTiltCommand(new byte[] { 0x03, 0x01 }, false);
|
||||
// IsMoving = true;
|
||||
}
|
||||
// IsMoving = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// TiltStop method
|
||||
/// </summary>
|
||||
@@ -517,28 +544,28 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
Stop();
|
||||
}
|
||||
|
||||
private void SendZoomCommand (byte cmd)
|
||||
{
|
||||
SendBytes(new byte[] {ID, 0x01, 0x04, 0x07, cmd, 0xFF} );
|
||||
}
|
||||
private void SendZoomCommand(byte cmd)
|
||||
{
|
||||
SendBytes(new byte[] { ID, 0x01, 0x04, 0x07, cmd, 0xFF });
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ZoomIn method
|
||||
/// </summary>
|
||||
public void ZoomIn()
|
||||
{
|
||||
/// <summary>
|
||||
/// ZoomIn method
|
||||
/// </summary>
|
||||
public void ZoomIn()
|
||||
{
|
||||
SendZoomCommand(ZoomInCmd);
|
||||
IsZooming = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// ZoomOut method
|
||||
/// </summary>
|
||||
public void ZoomOut()
|
||||
{
|
||||
IsZooming = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// ZoomOut method
|
||||
/// </summary>
|
||||
public void ZoomOut()
|
||||
{
|
||||
SendZoomCommand(ZoomOutCmd);
|
||||
IsZooming = true;
|
||||
}
|
||||
IsZooming = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// ZoomStop method
|
||||
/// </summary>
|
||||
@@ -547,23 +574,23 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop method
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (IsZooming)
|
||||
{
|
||||
/// <summary>
|
||||
/// Stop method
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (IsZooming)
|
||||
{
|
||||
SendZoomCommand(ZoomStopCmd);
|
||||
IsZooming = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsZooming = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
StopSpeedTimer();
|
||||
SendPanTiltCommand(new byte[] { 0x03, 0x03 }, false);
|
||||
// IsMoving = false;
|
||||
}
|
||||
}
|
||||
// IsMoving = false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// PositionHome method
|
||||
/// </summary>
|
||||
@@ -572,33 +599,39 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
SendBytes(new byte[] { ID, 0x01, 0x06, 0x02, PanSpeedFast, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF });
|
||||
SendBytes(new byte[] { ID, 0x01, 0x04, 0x47, 0x00, 0x00, 0x00, 0x00, 0xFF });
|
||||
}
|
||||
/// <summary>
|
||||
/// RecallPreset method
|
||||
/// </summary>
|
||||
public void RecallPreset(int presetNumber)
|
||||
{
|
||||
SendBytes(new byte[] {ID, 0x01, 0x04, 0x3F, 0x02, (byte)presetNumber, 0xFF} );
|
||||
}
|
||||
/// <summary>
|
||||
/// SavePreset method
|
||||
/// </summary>
|
||||
public void SavePreset(int presetNumber)
|
||||
{
|
||||
SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF });
|
||||
}
|
||||
/// <summary>
|
||||
/// RecallPreset method
|
||||
/// </summary>
|
||||
public void RecallPreset(int presetNumber)
|
||||
{
|
||||
SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x02, (byte)presetNumber, 0xFF });
|
||||
}
|
||||
/// <summary>
|
||||
/// SavePreset method
|
||||
/// </summary>
|
||||
public void SavePreset(int presetNumber)
|
||||
{
|
||||
SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF });
|
||||
}
|
||||
|
||||
#region IHasCameraPresets Members
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when the presets list has changed
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> PresetsListHasChanged;
|
||||
|
||||
protected void OnPresetsListHasChanged()
|
||||
{
|
||||
var handler = PresetsListHasChanged;
|
||||
if (handler == null)
|
||||
return;
|
||||
/// <summary>
|
||||
/// Raises the PresetsListHasChanged event
|
||||
/// </summary>
|
||||
protected void OnPresetsListHasChanged()
|
||||
{
|
||||
var handler = PresetsListHasChanged;
|
||||
if (handler == null)
|
||||
return;
|
||||
|
||||
handler.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
handler.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Presets
|
||||
@@ -741,6 +774,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
/// </summary>
|
||||
public class CameraViscaFactory : EssentialsDeviceFactory<CameraVisca>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CameraViscaFactory class
|
||||
/// </summary>
|
||||
public CameraViscaFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "cameravisca" };
|
||||
@@ -768,11 +804,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Control ID of the camera (1-7)
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Id
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public uint Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -790,7 +824,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
/// <summary>
|
||||
/// Slow tilt speed (0-18)
|
||||
/// </summary>
|
||||
[JsonProperty("tiltSpeedSlow")]
|
||||
[JsonProperty("tiltSpeedSlow")]
|
||||
public uint TiltSpeedSlow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
@@ -11,12 +8,27 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
/// </summary>
|
||||
public interface IHasCameraPresets
|
||||
{
|
||||
/// <summary>
|
||||
/// Event that is raised when the presets list has changed
|
||||
/// </summary>
|
||||
event EventHandler<EventArgs> PresetsListHasChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of camera presets
|
||||
/// </summary>
|
||||
List<CameraPreset> Presets { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Selects the specified preset
|
||||
/// </summary>
|
||||
/// <param name="preset">The preset number to select</param>
|
||||
void PresetSelect(int preset);
|
||||
|
||||
/// <summary>
|
||||
/// Stores a preset at the specified location with the given description
|
||||
/// </summary>
|
||||
/// <param name="preset">The preset number to store</param>
|
||||
/// <param name="description">The description for the preset</param>
|
||||
void PresetStore(int preset, string description);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Event arguments for the CameraSelected event
|
||||
/// </summary>
|
||||
[Obsolete("Use CameraSelectedEventArgs<T> instead. This class will be removed in a future version")]
|
||||
public class CameraSelectedEventArgs : EventArgs
|
||||
{
|
||||
/// Gets or sets the SelectedCamera
|
||||
/// </summary>
|
||||
public CameraBase SelectedCamera { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for CameraSelectedEventArgs
|
||||
/// </summary>
|
||||
/// <param name="camera"></param>
|
||||
public CameraSelectedEventArgs(CameraBase camera)
|
||||
{
|
||||
SelectedCamera = camera;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event arguments for the CameraSelected event
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class CameraSelectedEventArgs<T> : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the SelectedCamera
|
||||
/// </summary>
|
||||
public T SelectedCamera { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for CameraSelectedEventArgs
|
||||
/// </summary>
|
||||
/// <param name="camera"></param>
|
||||
public CameraSelectedEventArgs(T camera)
|
||||
{
|
||||
SelectedCamera = camera;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IAmFarEndCamera
|
||||
/// </summary>
|
||||
public interface IAmFarEndCamera : IKeyName
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for camera capabilities
|
||||
/// </summary>
|
||||
public interface ICameraCapabilities: IKeyName
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can pan
|
||||
/// </summary>
|
||||
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
|
||||
bool CanPan { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can tilt
|
||||
/// </summary>
|
||||
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
|
||||
bool CanTilt { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can zoom
|
||||
/// </summary>
|
||||
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||
bool CanZoom { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can focus
|
||||
/// </summary>
|
||||
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
|
||||
bool CanFocus { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the capabilities of a camera
|
||||
/// </summary>
|
||||
public class CameraCapabilities : ICameraCapabilities
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Unique Key
|
||||
/// </summary>
|
||||
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Isn't it obvious :)
|
||||
/// </summary>
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Name { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can pan
|
||||
/// </summary>
|
||||
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanPan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can tilt
|
||||
/// </summary>
|
||||
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanTilt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can zoom
|
||||
/// </summary>
|
||||
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanZoom { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can focus
|
||||
/// </summary>
|
||||
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanFocus { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for devices that have auto focus mode control
|
||||
/// </summary>
|
||||
public interface IHasAutoFocusMode : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the focus mode to auto or manual, or toggles between them.
|
||||
/// </summary>
|
||||
void SetFocusModeAuto();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the focus mode to manual, allowing for manual focus adjustments.
|
||||
/// </summary>
|
||||
void SetFocusModeManual();
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the focus mode between auto and manual.
|
||||
/// </summary>
|
||||
void ToggleFocusMode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Interface for devices that have camera auto mode control
|
||||
/// </summary>
|
||||
public interface IHasCameraAutoMode : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Enables or disables the camera's auto mode, which may include automatic adjustments for focus, exposure, and other settings.
|
||||
/// </summary>
|
||||
void CameraAutoModeOn();
|
||||
|
||||
/// <summary>
|
||||
/// Disables the camera's auto mode, allowing for manual control of camera settings.
|
||||
/// </summary>
|
||||
void CameraAutoModeOff();
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the camera's auto mode state. If the camera is in auto mode, it will switch to manual mode, and vice versa.
|
||||
/// </summary>
|
||||
void CameraAutoModeToggle();
|
||||
|
||||
/// <summary>
|
||||
/// Feedback that indicates whether the camera's auto mode is currently enabled.
|
||||
/// </summary>
|
||||
BoolFeedback CameraAutoModeIsOnFeedback { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using PepperDash.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Interface for devices that have camera controls
|
||||
/// </summary>
|
||||
public interface IHasCameraControls : IKeyName
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCameraFocusControl
|
||||
/// </summary>
|
||||
public interface IHasCameraFocusControl : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Focuses the camera near
|
||||
/// </summary>
|
||||
void FocusNear();
|
||||
|
||||
/// <summary>
|
||||
/// Focuses the camera far
|
||||
/// </summary>
|
||||
void FocusFar();
|
||||
|
||||
/// <summary>
|
||||
/// Stops the camera focus movement
|
||||
/// </summary>
|
||||
void FocusStop();
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the camera's auto focus functionality, if available.
|
||||
/// </summary>
|
||||
void TriggerAutoFocus();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the ability to mute and unmute camera video
|
||||
/// </summary>
|
||||
public interface IHasCameraMute : IKeyName
|
||||
{
|
||||
/// <summary>
|
||||
/// Feedback that indicates whether the camera is muted
|
||||
/// </summary>
|
||||
BoolFeedback CameraIsMutedFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Mutes the camera video, preventing it from being sent to the far end
|
||||
/// </summary>
|
||||
void CameraMuteOn();
|
||||
|
||||
/// <summary>
|
||||
/// Unmutes the camera video, allowing it to be sent to the far end
|
||||
/// </summary>
|
||||
void CameraMuteOff();
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the camera mute state. If the camera is muted, it will be unmuted, and vice versa.
|
||||
/// </summary>
|
||||
void CameraMuteToggle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for devices that can mute and unmute their camera video, with an event for unmute requests
|
||||
/// </summary>
|
||||
public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute
|
||||
{
|
||||
/// <summary>
|
||||
/// Event that is raised when a video unmute is requested, typically by the far end
|
||||
/// </summary>
|
||||
event EventHandler VideoUnmuteRequested;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// To be implmented on codecs that can disable their camera(s) to blank the near end video
|
||||
/// </summary>
|
||||
public interface IHasCameraOff : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Feedback that indicates whether the camera is off
|
||||
/// </summary>
|
||||
BoolFeedback CameraIsOffFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Turns the camera off, blanking the near end video
|
||||
/// </summary>
|
||||
void CameraOff();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for camera pan control
|
||||
/// </summary>
|
||||
public interface IHasCameraPanControl : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Pans the camera left
|
||||
/// </summary>
|
||||
void PanLeft();
|
||||
|
||||
/// <summary>
|
||||
/// Pans the camera right
|
||||
/// </summary>
|
||||
void PanRight();
|
||||
|
||||
/// <summary>
|
||||
/// Stops the camera pan movement
|
||||
/// </summary>
|
||||
void PanStop();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCameraPtzControl
|
||||
/// </summary>
|
||||
public interface IHasCameraPtzControl : IHasCameraPanControl, IHasCameraTiltControl, IHasCameraZoomControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Resets the camera position
|
||||
/// </summary>
|
||||
void PositionHome();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCameraTiltControl
|
||||
/// </summary>
|
||||
public interface IHasCameraTiltControl : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Tilts the camera down
|
||||
/// </summary>
|
||||
void TiltDown();
|
||||
|
||||
/// <summary>
|
||||
/// Tilts the camera up
|
||||
/// </summary>
|
||||
void TiltUp();
|
||||
|
||||
/// <summary>
|
||||
/// Stops the camera tilt movement
|
||||
/// </summary>
|
||||
void TiltStop();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCameraZoomControl
|
||||
/// </summary>
|
||||
public interface IHasCameraZoomControl : IHasCameraControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Zooms the camera in
|
||||
/// </summary>
|
||||
void ZoomIn();
|
||||
|
||||
/// <summary>
|
||||
/// Zooms the camera out
|
||||
/// </summary>
|
||||
void ZoomOut();
|
||||
|
||||
/// <summary>
|
||||
/// Stops the camera zoom movement
|
||||
/// </summary>
|
||||
void ZoomStop();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for devices that have cameras
|
||||
/// </summary>
|
||||
[Obsolete("Use IHasCamerasWithControls instead. This interface will be removed in a future version")]
|
||||
public interface IHasCameras : IKeyName
|
||||
{
|
||||
/// <summary>
|
||||
/// Event that is raised when a camera is selected
|
||||
/// </summary>
|
||||
event EventHandler<CameraSelectedEventArgs> CameraSelected;
|
||||
|
||||
/// <summary>
|
||||
/// List of cameras on the device. This should be a list of CameraBase objects
|
||||
/// </summary>
|
||||
List<CameraBase> Cameras { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The currently selected camera. This should be a CameraBase object
|
||||
/// </summary>
|
||||
CameraBase SelectedCamera { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Feedback that indicates the currently selected camera
|
||||
/// </summary>
|
||||
StringFeedback SelectedCameraFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Selects a camera from the list of available cameras based on the provided key.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier or name of the camera to select.</param>
|
||||
void SelectCamera(string key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for devices that have cameras with controls
|
||||
/// </summary>
|
||||
public interface IHasCamerasWithControls : IKeyName, IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// List of cameras on the device. This should be a list of IHasCameraControls objects
|
||||
/// </summary>
|
||||
|
||||
List<IHasCameraControls> Cameras { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The currently selected camera. This should be an IHasCameraControls object
|
||||
/// </summary>
|
||||
IHasCameraControls SelectedCamera { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Feedback that indicates the currently selected camera
|
||||
/// </summary>
|
||||
StringFeedback SelectedCameraFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when a camera is selected
|
||||
/// </summary>
|
||||
event EventHandler<CameraSelectedEventArgs<IHasCameraControls>> CameraSelected;
|
||||
|
||||
/// <summary>
|
||||
/// Selects a camera from the list of available cameras based on the provided key.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
void SelectCamera(string key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCodecCameras
|
||||
/// </summary>
|
||||
public interface IHasCodecCameras : IHasCameras, IHasFarEndCameraControl
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for devices that have a far end camera control
|
||||
/// </summary>
|
||||
public interface IHasFarEndCameraControl : IKeyName
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the far end camera, which is typically a CameraBase object that represents the camera at the far end of a call
|
||||
/// </summary>
|
||||
CameraBase FarEndCamera { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Feedback that indicates whether the far end camera is being controlled
|
||||
/// </summary>
|
||||
BoolFeedback ControllingFarEndCameraFeedback { get; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum for camera control modes
|
||||
/// </summary>
|
||||
public enum eCameraControlMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Manual control mode, where the camera is controlled directly by the user or system
|
||||
/// </summary>
|
||||
Manual = 0,
|
||||
/// <summary>
|
||||
/// Off control mode, where the camera is turned off or disabled
|
||||
/// </summary>
|
||||
Off,
|
||||
/// <summary>
|
||||
/// Auto control mode, where the camera automatically adjusts settings based on the environment or conditions
|
||||
/// </summary>
|
||||
Auto
|
||||
}
|
||||
|
||||
}
|
||||
26
src/PepperDash.Essentials.Devices.Common/Codec/Call.cs
Normal file
26
src/PepperDash.Essentials.Devices.Common/Codec/Call.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Call
|
||||
/// </summary>
|
||||
public class Call
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Number
|
||||
/// </summary>
|
||||
public string Number { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Protocol
|
||||
/// </summary>
|
||||
public string Protocol { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the CallRate
|
||||
/// </summary>
|
||||
public string CallRate { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the CallType
|
||||
/// </summary>
|
||||
public string CallType { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,5 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec.Cisco
|
||||
{
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec.Cisco
|
||||
{
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
@@ -17,55 +13,55 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public class CodecActiveCallItem
|
||||
{
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
/// <summary>
|
||||
/// Gets or sets the Name
|
||||
/// </summary>
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("number", NullValueHandling = NullValueHandling.Ignore)]
|
||||
/// <summary>
|
||||
/// Gets or sets the Number
|
||||
/// </summary>
|
||||
[JsonProperty("number", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Number { get; set; }
|
||||
|
||||
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
/// <summary>
|
||||
/// Gets or sets the Type
|
||||
/// </summary>
|
||||
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eCodecCallType Type { get; set; }
|
||||
|
||||
[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
/// <summary>
|
||||
/// Gets or sets the Status
|
||||
/// </summary>
|
||||
[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eCodecCallStatus Status { get; set; }
|
||||
|
||||
[JsonProperty("direction", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
/// <summary>
|
||||
/// Gets or sets the Direction
|
||||
/// </summary>
|
||||
[JsonProperty("direction", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eCodecCallDirection Direction { get; set; }
|
||||
|
||||
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
|
||||
/// <summary>
|
||||
/// Gets or sets the Id
|
||||
/// </summary>
|
||||
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty("isOnHold", NullValueHandling = NullValueHandling.Ignore)]
|
||||
/// <summary>
|
||||
/// Gets or sets the IsOnHold
|
||||
/// </summary>
|
||||
[JsonProperty("isOnHold", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool IsOnHold { get; set; }
|
||||
|
||||
[JsonProperty("duration", NullValueHandling = NullValueHandling.Ignore)]
|
||||
/// <summary>
|
||||
/// Gets or sets the Duration
|
||||
/// </summary>
|
||||
[JsonProperty("duration", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public TimeSpan Duration { get; set; }
|
||||
|
||||
//public object CallMetaData { get; set; }
|
||||
@@ -81,7 +77,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
return !(Status == eCodecCallStatus.Disconnected
|
||||
|| Status == eCodecCallStatus.Disconnecting
|
||||
|| Status == eCodecCallStatus.Idle
|
||||
|| Status == eCodecCallStatus.Idle
|
||||
|| Status == eCodecCallStatus.Unknown);
|
||||
}
|
||||
}
|
||||
@@ -97,6 +93,10 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public CodecActiveCallItem CallItem { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CodecCallStatusItemChangeEventArgs class
|
||||
/// </summary>
|
||||
/// <param name="item">The call item that changed</param>
|
||||
public CodecCallStatusItemChangeEventArgs(CodecActiveCallItem item)
|
||||
{
|
||||
CallItem = item;
|
||||
|
||||
121
src/PepperDash.Essentials.Devices.Common/Codec/CodecDirectory.cs
Normal file
121
src/PepperDash.Essentials.Devices.Common/Codec/CodecDirectory.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a codec directory
|
||||
/// </summary>
|
||||
public class CodecDirectory
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the contents of the directory
|
||||
/// We don't want to serialize this for messages to MobileControl. MC can combine Contacts and Folders to get the same data
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public List<DirectoryItem> CurrentDirectoryResults { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Contacts in the CurrentDirectoryResults
|
||||
/// </summary>
|
||||
[JsonProperty("contacts")]
|
||||
public List<DirectoryItem> Contacts
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentDirectoryResults.OfType<DirectoryContact>().Cast<DirectoryItem>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Folders in the CurrentDirectoryResults
|
||||
/// </summary>
|
||||
[JsonProperty("folders")]
|
||||
public List<DirectoryItem> Folders
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentDirectoryResults.OfType<DirectoryFolder>().Cast<DirectoryItem>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to store the ID of the current folder for CurrentDirectoryResults
|
||||
/// Gets or sets the ResultsFolderId
|
||||
/// </summary>
|
||||
[JsonProperty("resultsFolderId")]
|
||||
public string ResultsFolderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for <see cref="CodecDirectory"/>
|
||||
/// </summary>
|
||||
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>
|
||||
/// Filters the CurrentDirectoryResults by the predicate
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
|
||||
public void FilterContacts(Func<DirectoryItem, bool> predicate)
|
||||
{
|
||||
CurrentDirectoryResults = CurrentDirectoryResults.Where(predicate).ToList();
|
||||
}
|
||||
|
||||
/// <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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a CodecScheduleAwareness
|
||||
/// </summary>
|
||||
public class CodecScheduleAwareness
|
||||
{
|
||||
List<Meeting> _meetings;
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when a meeting event changes
|
||||
/// </summary>
|
||||
public event EventHandler<MeetingEventArgs> MeetingEventChange;
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when the meetings list has changed
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> MeetingsListHasChanged;
|
||||
|
||||
private int _meetingWarningMinutes = 5;
|
||||
|
||||
//private Meeting _previousChangedMeeting;
|
||||
|
||||
//private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of minutes before a meeting to issue a warning
|
||||
/// </summary>
|
||||
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;
|
||||
MeetingsListHasChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
private readonly CTimer _scheduleChecker;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CodecScheduleAwareness class with default poll time
|
||||
/// </summary>
|
||||
public CodecScheduleAwareness()
|
||||
{
|
||||
Meetings = new List<Meeting>();
|
||||
|
||||
_scheduleChecker = new CTimer(CheckSchedule, null, 1000, 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CodecScheduleAwareness class with specified poll time
|
||||
/// </summary>
|
||||
/// <param name="pollTime">The poll time in milliseconds for checking schedule changes</param>
|
||||
public CodecScheduleAwareness(long pollTime)
|
||||
{
|
||||
Meetings = new List<Meeting>();
|
||||
|
||||
_scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to fire MeetingEventChange. Should only fire once for each changeType on each meeting
|
||||
/// </summary>
|
||||
/// <param name="changeType"></param>
|
||||
/// <param name="meeting"></param>
|
||||
private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "*****************OnMeetingChange. id: {0} changeType: {1}**********************", meeting.Id, changeType);
|
||||
if (changeType != (changeType & meeting.NotifiedChangeTypes))
|
||||
{
|
||||
// Add this change type to the NotifiedChangeTypes
|
||||
meeting.NotifiedChangeTypes |= changeType;
|
||||
MeetingEventChange?.Invoke(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Meeting: {0} already notified of changeType: {1}", meeting.Id, changeType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks the schedule to see if any MeetingEventChange updates should be fired
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
private void CheckSchedule(object o)
|
||||
{
|
||||
// Iterate the meeting list and check if any meeting need to do anything
|
||||
|
||||
const double meetingTimeEpsilon = 0.05;
|
||||
foreach (var m in Meetings)
|
||||
{
|
||||
var changeType = eMeetingEventChangeType.Unknown;
|
||||
|
||||
if (eMeetingEventChangeType.MeetingStartWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStartWarning) && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds);
|
||||
changeType = eMeetingEventChangeType.MeetingStartWarning;
|
||||
}
|
||||
else if (eMeetingEventChangeType.MeetingStart != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStart) && Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStart");
|
||||
changeType = eMeetingEventChangeType.MeetingStart;
|
||||
}
|
||||
else if (eMeetingEventChangeType.MeetingEndWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEndWarning) && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEndWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingEnd.TotalMinutes, m.TimeToMeetingEnd.Seconds);
|
||||
changeType = eMeetingEventChangeType.MeetingEndWarning;
|
||||
}
|
||||
else if (eMeetingEventChangeType.MeetingEnd != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEnd) && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEnd");
|
||||
changeType = eMeetingEventChangeType.MeetingEnd;
|
||||
}
|
||||
|
||||
if (changeType != eMeetingEventChangeType.Unknown)
|
||||
{
|
||||
OnMeetingChange(changeType, m);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a ContactMethod
|
||||
/// </summary>
|
||||
public class ContactMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ContactMethodId
|
||||
/// </summary>
|
||||
[JsonProperty("contactMethodId")]
|
||||
public string ContactMethodId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Number
|
||||
/// </summary>
|
||||
[JsonProperty("number")]
|
||||
public string Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Device
|
||||
/// </summary>
|
||||
[JsonProperty("device")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eContactMethodDevice Device { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CallType
|
||||
/// </summary>
|
||||
[JsonProperty("callType")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eContactMethodCallType CallType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a DirectoryContact
|
||||
/// </summary>
|
||||
public class DirectoryContact : DirectoryItem
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ContactId
|
||||
/// </summary>
|
||||
[JsonProperty("contactId")]
|
||||
public string ContactId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Title
|
||||
/// </summary>
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ContactMethods
|
||||
/// </summary>
|
||||
[JsonProperty("contactMethods")]
|
||||
public List<ContactMethod> ContactMethods { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for <see cref="DirectoryContact"/>
|
||||
/// </summary>
|
||||
public DirectoryContact()
|
||||
{
|
||||
ContactMethods = new List<ContactMethod>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a DirectoryEventArgs
|
||||
/// </summary>
|
||||
public class DirectoryEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Directory
|
||||
/// </summary>
|
||||
public CodecDirectory Directory { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the DirectoryIsOnRoot
|
||||
/// </summary>
|
||||
public bool DirectoryIsOnRoot { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a DirectoryFolder
|
||||
/// </summary>
|
||||
public class DirectoryFolder : DirectoryItem
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Contacts
|
||||
/// </summary>
|
||||
[JsonProperty("contacts")]
|
||||
public List<DirectoryContact> Contacts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for <see cref="DirectoryFolder"/>
|
||||
/// </summary>
|
||||
public DirectoryFolder()
|
||||
{
|
||||
Contacts = new List<DirectoryContact>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a DirectoryItem
|
||||
/// </summary>
|
||||
public class DirectoryItem : ICloneable
|
||||
{
|
||||
/// <summary>
|
||||
/// Clone method
|
||||
/// </summary>
|
||||
public object Clone()
|
||||
{
|
||||
return MemberwiseClone();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the FolderId
|
||||
/// </summary>
|
||||
[JsonProperty("folderId")]
|
||||
public string FolderId { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Name
|
||||
/// </summary>
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ParentFolderId
|
||||
/// </summary>
|
||||
[JsonProperty("parentFolderId")]
|
||||
public string ParentFolderId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,65 @@
|
||||
using Crestron.SimplSharpPro;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes a cisco codec device that can allow configuration of cameras
|
||||
/// </summary>
|
||||
public interface ICiscoCodecCameraConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the assigned serial number for the specified camera
|
||||
/// </summary>
|
||||
/// <param name="cameraId">The camera identifier</param>
|
||||
/// <param name="serialNumber">The serial number to assign</param>
|
||||
void SetCameraAssignedSerialNumber(uint cameraId, string serialNumber);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the name for the camera on the specified video connector
|
||||
/// </summary>
|
||||
/// <param name="videoConnectorId">The video connector identifier</param>
|
||||
/// <param name="name">The name to assign</param>
|
||||
void SetCameraName(uint videoConnectorId, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the input source type for the specified video connector
|
||||
/// </summary>
|
||||
/// <param name="videoConnectorId">The video connector identifier</param>
|
||||
/// <param name="sourceType">The source type to set</param>
|
||||
void SetInputSourceType(uint videoConnectorId, eCiscoCodecInputSourceType sourceType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumeration of Cisco codec input source types
|
||||
/// </summary>
|
||||
public enum eCiscoCodecInputSourceType
|
||||
{
|
||||
/// <summary>
|
||||
/// PC source type
|
||||
/// </summary>
|
||||
PC,
|
||||
|
||||
/// <summary>
|
||||
/// Camera source type
|
||||
/// </summary>
|
||||
camera,
|
||||
|
||||
/// <summary>
|
||||
/// Document camera source type
|
||||
/// </summary>
|
||||
document_camera,
|
||||
|
||||
/// <summary>
|
||||
/// Media player source type
|
||||
/// </summary>
|
||||
mediaplayer,
|
||||
|
||||
/// <summary>
|
||||
/// Other source type
|
||||
/// </summary>
|
||||
other,
|
||||
|
||||
/// <summary>
|
||||
/// Whiteboard source type
|
||||
/// </summary>
|
||||
whiteboard
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasCallHold
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasDirectoryHistoryStack
|
||||
/// </summary>
|
||||
public interface IHasDirectoryHistoryStack : IHasDirectory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the DirectoryBrowseHistoryStack
|
||||
/// </summary>
|
||||
Stack<CodecDirectory> DirectoryBrowseHistoryStack { get; }
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
@@ -34,6 +28,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
void ToggleDoNotDisturbMode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for devices that support Do Not Disturb mode with timeout functionality
|
||||
/// </summary>
|
||||
public interface IHasDoNotDisturbModeWithTimeout : IHasDoNotDisturbMode
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,25 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasExternalSourceSwitching
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasExternalSourceSwitching
|
||||
/// </summary>
|
||||
public interface IHasExternalSourceSwitching
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the external source list is enabled
|
||||
/// </summary>
|
||||
bool ExternalSourceListEnabled { get; }
|
||||
string ExternalSourceInputPort { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the external source input port identifier
|
||||
/// </summary>
|
||||
string ExternalSourceInputPort { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds an external source to the available sources
|
||||
/// </summary>
|
||||
/// <param name="connectorId">The connector identifier</param>
|
||||
/// <param name="key">The unique key for the source</param>
|
||||
/// <param name="name">The display name for the source</param>
|
||||
/// <param name="type">The type of external source</param>
|
||||
void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the state of the specified external source
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key of the external source</param>
|
||||
/// <param name="mode">The mode to set for the source</param>
|
||||
void SetExternalSourceState(string key, eExternalSourceMode mode);
|
||||
|
||||
/// <summary>
|
||||
/// Clears all external sources from the list
|
||||
/// </summary>
|
||||
void ClearExternalSources();
|
||||
void SetSelectedSource(string key);
|
||||
Action<string, string> RunRouteAction { set;}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the selected source by its key
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key of the source to select</param>
|
||||
void SetSelectedSource(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the action to run when routing between sources
|
||||
/// </summary>
|
||||
Action<string, string> RunRouteAction { set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IInvitableContact
|
||||
/// </summary>
|
||||
public interface IInvitableContact
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this contact is invitable
|
||||
/// </summary>
|
||||
bool IsInvitableContact { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an InvitableDirectoryContact
|
||||
/// </summary>
|
||||
public class InvitableDirectoryContact : DirectoryContact, IInvitableContact
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this contact is invitable
|
||||
/// </summary>
|
||||
[JsonProperty("isInvitableContact")]
|
||||
public bool IsInvitableContact
|
||||
{
|
||||
get
|
||||
{
|
||||
return this is IInvitableContact;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
182
src/PepperDash.Essentials.Devices.Common/Codec/Meeting.cs
Normal file
182
src/PepperDash.Essentials.Devices.Common/Codec/Meeting.cs
Normal file
@@ -0,0 +1,182 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Meeting
|
||||
/// </summary>
|
||||
public class Meeting
|
||||
{
|
||||
/// <summary>
|
||||
/// Minutes before the meeting to show warning
|
||||
/// </summary>
|
||||
[JsonProperty("minutesBeforeMeeting")]
|
||||
public int MinutesBeforeMeeting;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the meeting ID
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the meeting organizer
|
||||
/// </summary>
|
||||
[JsonProperty("organizer")]
|
||||
public string Organizer { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Title
|
||||
/// </summary>
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Agenda
|
||||
/// </summary>
|
||||
[JsonProperty("agenda")]
|
||||
public string Agenda { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the meeting warning time span in minutes before the meeting starts
|
||||
/// </summary>
|
||||
[JsonProperty("meetingWarningMinutes")]
|
||||
public TimeSpan MeetingWarningMinutes
|
||||
{
|
||||
get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the time remaining until the meeting starts
|
||||
/// </summary>
|
||||
[JsonProperty("timeToMeetingStart")]
|
||||
public TimeSpan TimeToMeetingStart
|
||||
{
|
||||
get
|
||||
{
|
||||
return StartTime - DateTime.Now;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the time remaining until the meeting ends
|
||||
/// </summary>
|
||||
[JsonProperty("timeToMeetingEnd")]
|
||||
public TimeSpan TimeToMeetingEnd
|
||||
{
|
||||
get
|
||||
{
|
||||
return EndTime - DateTime.Now;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the StartTime
|
||||
/// </summary>
|
||||
[JsonProperty("startTime")]
|
||||
public DateTime StartTime { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the EndTime
|
||||
/// </summary>
|
||||
[JsonProperty("endTime")]
|
||||
public DateTime EndTime { get; set; }
|
||||
/// <summary>
|
||||
/// Gets the duration of the meeting
|
||||
/// </summary>
|
||||
[JsonProperty("duration")]
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return EndTime - StartTime;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the Privacy
|
||||
/// </summary>
|
||||
[JsonProperty("privacy")]
|
||||
public eMeetingPrivacy Privacy { get; set; }
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the meeting can be joined
|
||||
/// </summary>
|
||||
[JsonProperty("joinable")]
|
||||
public bool Joinable
|
||||
{
|
||||
get
|
||||
{
|
||||
var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now
|
||||
&& DateTime.Now <= EndTime.AddSeconds(-_joinableCooldownSeconds);
|
||||
//Debug.LogMessage(LogEventLevel.Verbose, "Meeting Id: {0} joinable: {1}", Id, joinable);
|
||||
return joinable;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Dialable
|
||||
/// </summary>
|
||||
[JsonProperty("dialable")]
|
||||
public bool Dialable { get; set; }
|
||||
|
||||
//public string ConferenceNumberToDial { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ConferencePassword
|
||||
/// </summary>
|
||||
[JsonProperty("conferencePassword")]
|
||||
public string ConferencePassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the IsOneButtonToPushMeeting
|
||||
/// </summary>
|
||||
[JsonProperty("isOneButtonToPushMeeting")]
|
||||
public bool IsOneButtonToPushMeeting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Calls
|
||||
/// </summary>
|
||||
[JsonProperty("calls")]
|
||||
public List<Call> Calls { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the change types that have already been notified for
|
||||
/// Gets or sets the NotifiedChangeTypes
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public eMeetingEventChangeType NotifiedChangeTypes { get; set; }
|
||||
|
||||
[JsonIgnore] private readonly int _joinableCooldownSeconds;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for Meeting <see cref="Meeting"/>
|
||||
/// </summary>
|
||||
public Meeting()
|
||||
{
|
||||
Calls = new List<Call>();
|
||||
_joinableCooldownSeconds = 300;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for Meeting <see cref="Meeting"/>
|
||||
/// </summary>
|
||||
/// <param name="joinableCooldownSeconds">Number of seconds after meeting start when it is no longer joinable</param>
|
||||
public Meeting(int joinableCooldownSeconds)
|
||||
{
|
||||
Calls = new List<Call>();
|
||||
_joinableCooldownSeconds = joinableCooldownSeconds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region Overrides of Object
|
||||
|
||||
/// <summary>
|
||||
/// ToString method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}:{1}: {2}-{3}", Title, Agenda, StartTime, EndTime);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a MeetingEventArgs
|
||||
/// </summary>
|
||||
public class MeetingEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ChangeType
|
||||
/// </summary>
|
||||
public eMeetingEventChangeType ChangeType { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Meeting
|
||||
/// </summary>
|
||||
public Meeting Meeting { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
@@ -12,7 +6,20 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public enum eCodecCallDirection
|
||||
{
|
||||
Unknown = 0, Incoming, Outgoing
|
||||
/// <summary>
|
||||
/// Unknown call direction
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Incoming call direction
|
||||
/// </summary>
|
||||
Incoming,
|
||||
|
||||
/// <summary>
|
||||
/// Outgoing call direction
|
||||
/// </summary>
|
||||
Outgoing
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,27 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration of eCodecCallStatus values
|
||||
/// </summary>
|
||||
public enum eCodecCallStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Unknown call status
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
Connected,
|
||||
Connecting,
|
||||
Dialing,
|
||||
|
||||
/// <summary>
|
||||
/// Call is connected
|
||||
/// </summary>
|
||||
Connected,
|
||||
|
||||
/// <summary>
|
||||
/// Call is connecting
|
||||
/// </summary>
|
||||
Connecting,
|
||||
|
||||
/// <summary>
|
||||
/// Call is dialing
|
||||
/// </summary>
|
||||
Dialing,
|
||||
|
||||
/// <summary>
|
||||
/// Call is disconnected
|
||||
/// </summary>
|
||||
Disconnected,
|
||||
Disconnecting,
|
||||
EarlyMedia,
|
||||
|
||||
/// <summary>
|
||||
/// Call is disconnecting
|
||||
/// </summary>
|
||||
Disconnecting,
|
||||
|
||||
/// <summary>
|
||||
/// Early media is being sent/received
|
||||
/// </summary>
|
||||
EarlyMedia,
|
||||
|
||||
/// <summary>
|
||||
/// Call is idle
|
||||
/// </summary>
|
||||
Idle,
|
||||
OnHold,
|
||||
Ringing,
|
||||
Preserved,
|
||||
|
||||
/// <summary>
|
||||
/// Call is on hold
|
||||
/// </summary>
|
||||
OnHold,
|
||||
|
||||
/// <summary>
|
||||
/// Call is ringing
|
||||
/// </summary>
|
||||
Ringing,
|
||||
|
||||
/// <summary>
|
||||
/// Call is preserved
|
||||
/// </summary>
|
||||
Preserved,
|
||||
|
||||
/// <summary>
|
||||
/// Call is remote preserved
|
||||
/// </summary>
|
||||
RemotePreserved,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
@@ -12,10 +6,29 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public enum eCodecCallType
|
||||
{
|
||||
Unknown = 0,
|
||||
Audio,
|
||||
Video,
|
||||
AudioCanEscalate,
|
||||
/// <summary>
|
||||
/// Unknown call type
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Audio-only call type
|
||||
/// </summary>
|
||||
Audio,
|
||||
|
||||
/// <summary>
|
||||
/// Video call type
|
||||
/// </summary>
|
||||
Video,
|
||||
|
||||
/// <summary>
|
||||
/// Audio call that can be escalated to video
|
||||
/// </summary>
|
||||
AudioCanEscalate,
|
||||
|
||||
/// <summary>
|
||||
/// Forward all call type
|
||||
/// </summary>
|
||||
ForwardAllCall
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration of eContactMethodCallType values
|
||||
/// </summary>
|
||||
public enum eContactMethodCallType
|
||||
{
|
||||
/// <summary>
|
||||
/// Unknown call type
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
/// <summary>
|
||||
/// Audio call type
|
||||
/// </summary>
|
||||
Audio,
|
||||
/// <summary>
|
||||
/// Video call type
|
||||
/// </summary>
|
||||
Video
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration of eContactMethodDevice values
|
||||
/// </summary>
|
||||
public enum eContactMethodDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Unknown contact method
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
/// <summary>
|
||||
/// Mobile contact method
|
||||
/// </summary>
|
||||
Mobile,
|
||||
/// <summary>
|
||||
/// Other contact method
|
||||
/// </summary>
|
||||
Other,
|
||||
/// <summary>
|
||||
/// Telephone contact method
|
||||
/// </summary>
|
||||
Telephone,
|
||||
/// <summary>
|
||||
/// Video contact method
|
||||
/// </summary>
|
||||
Video
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration of eMeetingEventChangeType values
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum eMeetingEventChangeType
|
||||
{
|
||||
/// <summary>
|
||||
/// Unknown change type
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
/// <summary>
|
||||
/// Meeting start warning
|
||||
/// </summary>
|
||||
MeetingStartWarning = 1,
|
||||
/// <summary>
|
||||
/// Meeting start
|
||||
/// </summary>
|
||||
MeetingStart = 2,
|
||||
/// <summary>
|
||||
/// Meeting end warning
|
||||
/// </summary>
|
||||
MeetingEndWarning = 4,
|
||||
/// <summary>
|
||||
/// Meeting end
|
||||
/// </summary>
|
||||
MeetingEnd = 8
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration of eMeetingPrivacy values
|
||||
/// </summary>
|
||||
public enum eMeetingPrivacy
|
||||
{
|
||||
/// <summary>
|
||||
/// Unknown meeting privacy level
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Public meeting
|
||||
/// </summary>
|
||||
Public,
|
||||
|
||||
/// <summary>
|
||||
/// Private meeting
|
||||
/// </summary>
|
||||
Private
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
@@ -11,6 +7,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public interface IHasCallFavorites
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the call favorites for this device
|
||||
/// </summary>
|
||||
CodecCallFavorites CallFavorites { get; }
|
||||
}
|
||||
|
||||
@@ -24,6 +23,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public List<CodecActiveCallItem> Favorites { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CodecCallFavorites class
|
||||
/// </summary>
|
||||
public CodecCallFavorites()
|
||||
{
|
||||
Favorites = new List<CodecActiveCallItem>();
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
@@ -15,8 +14,15 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public interface IHasCallHistory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the call history for this device
|
||||
/// </summary>
|
||||
CodecCallHistory CallHistory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified call history entry
|
||||
/// </summary>
|
||||
/// <param name="entry">The call history entry to remove</param>
|
||||
void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry);
|
||||
}
|
||||
|
||||
@@ -25,9 +31,24 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public enum eCodecOccurrenceType
|
||||
{
|
||||
/// <summary>
|
||||
/// Unknown occurrence type
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Call was placed (outgoing)
|
||||
/// </summary>
|
||||
Placed = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Call was received (incoming)
|
||||
/// </summary>
|
||||
Received = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Call received no answer
|
||||
/// </summary>
|
||||
NoAnswer = 3,
|
||||
}
|
||||
|
||||
@@ -36,6 +57,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public class CodecCallHistory
|
||||
{
|
||||
/// <summary>
|
||||
/// Event that is raised when the recent calls list has changed
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> RecentCallsListHasChanged;
|
||||
|
||||
/// <summary>
|
||||
@@ -48,6 +72,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
CallHistoryEntry ListEmptyEntry;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CodecCallHistory class
|
||||
/// </summary>
|
||||
public CodecCallHistory()
|
||||
{
|
||||
ListEmptyEntry = new CallHistoryEntry() { Name = "No Recent Calls" };
|
||||
@@ -80,15 +107,22 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public class CallHistoryEntry : CodecActiveCallItem
|
||||
{
|
||||
[JsonConverter(typeof(IsoDateTimeConverter))]
|
||||
[JsonProperty("startTime")]
|
||||
/// <summary>
|
||||
/// Gets or sets the StartTime
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(IsoDateTimeConverter))]
|
||||
[JsonProperty("startTime")]
|
||||
public DateTime StartTime { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the occurrence type for this call history entry
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonProperty("occurrenceType")]
|
||||
public eCodecOccurrenceType OccurrenceType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the occurrence history identifier
|
||||
/// </summary>
|
||||
[JsonProperty("occurrenceHistoryId")]
|
||||
public string OccurrenceHistoryId { get; set; }
|
||||
}
|
||||
@@ -119,7 +153,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
}
|
||||
|
||||
// Check if list is empty and if so, add an item to display No Recent Calls
|
||||
if(genericEntries.Count == 0)
|
||||
if (genericEntries.Count == 0)
|
||||
genericEntries.Add(ListEmptyEntry);
|
||||
|
||||
RecentCalls = genericEntries;
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
@@ -15,12 +8,29 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public interface IHasContentSharing
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets feedback indicating whether content sharing is currently active
|
||||
/// </summary>
|
||||
BoolFeedback SharingContentIsOnFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets feedback about the current sharing source
|
||||
/// </summary>
|
||||
StringFeedback SharingSourceFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether content should be automatically shared while in a call
|
||||
/// </summary>
|
||||
bool AutoShareContentWhileInCall { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Starts content sharing
|
||||
/// </summary>
|
||||
void StartSharing();
|
||||
|
||||
/// <summary>
|
||||
/// Stops content sharing
|
||||
/// </summary>
|
||||
void StopSharing();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
@@ -15,15 +9,49 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
// Add requirements for Dialer functionality
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when call status changes
|
||||
/// </summary>
|
||||
event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
|
||||
|
||||
/// <summary>
|
||||
/// Dials the specified number
|
||||
/// </summary>
|
||||
/// <param name="number">The number to dial</param>
|
||||
void Dial(string number);
|
||||
|
||||
/// <summary>
|
||||
/// Ends the specified active call
|
||||
/// </summary>
|
||||
/// <param name="activeCall">The active call to end</param>
|
||||
void EndCall(CodecActiveCallItem activeCall);
|
||||
|
||||
/// <summary>
|
||||
/// Ends all active calls
|
||||
/// </summary>
|
||||
void EndAllCalls();
|
||||
|
||||
/// <summary>
|
||||
/// Accepts the specified incoming call
|
||||
/// </summary>
|
||||
/// <param name="item">The call item to accept</param>
|
||||
void AcceptCall(CodecActiveCallItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Rejects the specified incoming call
|
||||
/// </summary>
|
||||
/// <param name="item">The call item to reject</param>
|
||||
void RejectCall(CodecActiveCallItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Sends DTMF digits during a call
|
||||
/// </summary>
|
||||
/// <param name="digit">The DTMF digit(s) to send</param>
|
||||
void SendDtmf(string digit);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the device is currently in a call
|
||||
/// </summary>
|
||||
bool IsInCall { get; }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,319 +1,59 @@
|
||||
|
||||
|
||||
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.Devices.Common.VideoCodec;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the API for codecs with a directory
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Defines the API for codecs with a directory
|
||||
/// </summary>
|
||||
public interface IHasDirectory
|
||||
{
|
||||
/// <summary>
|
||||
/// Event that fires when a directory result is returned from the codec
|
||||
/// </summary>
|
||||
event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DirectoryRoot
|
||||
/// </summary>
|
||||
CodecDirectory DirectoryRoot { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the CurrentDirectoryResult
|
||||
/// </summary>
|
||||
CodecDirectory CurrentDirectoryResult { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PhonebookSyncState
|
||||
/// </summary>
|
||||
CodecPhonebookSyncState PhonebookSyncState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Method to initiate a search of the directory on the server
|
||||
/// </summary>
|
||||
void SearchDirectory(string searchString);
|
||||
|
||||
/// <summary>
|
||||
/// Method to get the contents of a specific folder in the directory on the server
|
||||
/// </summary>
|
||||
void GetDirectoryFolderContents(string folderId);
|
||||
|
||||
/// <summary>
|
||||
/// Method to set the current directory to the root folder
|
||||
/// </summary>
|
||||
void SetCurrentDirectoryToRoot();
|
||||
|
||||
/// <summary>
|
||||
/// Method to get the contents of the parent folder in the directory on the server
|
||||
/// </summary>
|
||||
void GetDirectoryParentFolderContents();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the CurrentDirectoryResultIsNotDirectoryRoot
|
||||
/// </summary>
|
||||
BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasDirectoryHistoryStack
|
||||
/// </summary>
|
||||
public interface IHasDirectoryHistoryStack : IHasDirectory
|
||||
{
|
||||
Stack<CodecDirectory> DirectoryBrowseHistoryStack { get; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a DirectoryEventArgs
|
||||
/// </summary>
|
||||
public class DirectoryEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Directory
|
||||
/// </summary>
|
||||
public CodecDirectory Directory { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the DirectoryIsOnRoot
|
||||
/// </summary>
|
||||
public bool DirectoryIsOnRoot { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a codec directory
|
||||
/// </summary>
|
||||
public class CodecDirectory
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the contents of the directory
|
||||
/// We don't want to serialize this for messages to MobileControl. MC can combine Contacts and Folders to get the same data
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public List<DirectoryItem> CurrentDirectoryResults { get; private set; }
|
||||
|
||||
[JsonProperty("contacts")]
|
||||
public List<DirectoryItem> Contacts
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentDirectoryResults.OfType<DirectoryContact>().Cast<DirectoryItem>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("folders")]
|
||||
public List<DirectoryItem> Folders
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentDirectoryResults.OfType<DirectoryFolder>().Cast<DirectoryItem>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to store the ID of the current folder for CurrentDirectoryResults
|
||||
/// </summary>
|
||||
[JsonProperty("resultsFolderId")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ResultsFolderId
|
||||
/// </summary>
|
||||
public string ResultsFolderId { get; set; }
|
||||
|
||||
public CodecDirectory()
|
||||
{
|
||||
CurrentDirectoryResults = new List<DirectoryItem>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds folders to the directory
|
||||
/// </summary>
|
||||
/// <param name="folders"></param>
|
||||
/// <summary>
|
||||
/// AddFoldersToDirectory method
|
||||
/// </summary>
|
||||
public void AddFoldersToDirectory(List<DirectoryItem> folders)
|
||||
{
|
||||
if(folders != null)
|
||||
CurrentDirectoryResults.AddRange(folders);
|
||||
|
||||
SortDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds contacts to the directory
|
||||
/// </summary>
|
||||
/// <param name="contacts"></param>
|
||||
/// <summary>
|
||||
/// AddContactsToDirectory method
|
||||
/// </summary>
|
||||
public void AddContactsToDirectory(List<DirectoryItem> contacts)
|
||||
{
|
||||
if(contacts != null)
|
||||
CurrentDirectoryResults.AddRange(contacts);
|
||||
|
||||
SortDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters the CurrentDirectoryResults by the predicate
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <summary>
|
||||
/// FilterContacts method
|
||||
/// </summary>
|
||||
public void FilterContacts(Func<DirectoryItem, bool> predicate)
|
||||
{
|
||||
CurrentDirectoryResults = CurrentDirectoryResults.Where(predicate).ToList();
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// Defines the contract for IInvitableContact
|
||||
/// </summary>
|
||||
public interface IInvitableContact
|
||||
{
|
||||
bool IsInvitableContact { get; }
|
||||
}
|
||||
|
||||
public class InvitableDirectoryContact : DirectoryContact, IInvitableContact
|
||||
{
|
||||
[JsonProperty("isInvitableContact")]
|
||||
public bool IsInvitableContact
|
||||
{
|
||||
get
|
||||
{
|
||||
return this is IInvitableContact;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a DirectoryItem
|
||||
/// </summary>
|
||||
public class DirectoryItem : ICloneable
|
||||
{
|
||||
/// <summary>
|
||||
/// Clone method
|
||||
/// </summary>
|
||||
public object Clone()
|
||||
{
|
||||
return this.MemberwiseClone();
|
||||
}
|
||||
|
||||
[JsonProperty("folderId")]
|
||||
public string FolderId { get; set; }
|
||||
|
||||
[JsonProperty("name")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("parentFolderId")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ParentFolderId
|
||||
/// </summary>
|
||||
public string ParentFolderId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a DirectoryFolder
|
||||
/// </summary>
|
||||
public class DirectoryFolder : DirectoryItem
|
||||
{
|
||||
[JsonProperty("contacts")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Contacts
|
||||
/// </summary>
|
||||
public List<DirectoryContact> Contacts { get; set; }
|
||||
|
||||
|
||||
public DirectoryFolder()
|
||||
{
|
||||
Contacts = new List<DirectoryContact>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a DirectoryContact
|
||||
/// </summary>
|
||||
public class DirectoryContact : DirectoryItem
|
||||
{
|
||||
[JsonProperty("contactId")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ContactId
|
||||
/// </summary>
|
||||
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 ContactMethod
|
||||
/// </summary>
|
||||
public class ContactMethod
|
||||
{
|
||||
[JsonProperty("contactMethodId")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ContactMethodId
|
||||
/// </summary>
|
||||
public string ContactMethodId { get; set; }
|
||||
|
||||
[JsonProperty("number")]
|
||||
public string Number { get; set; }
|
||||
|
||||
[JsonProperty("device")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
/// <summary>
|
||||
/// Gets or sets the Device
|
||||
/// </summary>
|
||||
public eContactMethodDevice Device { get; set; }
|
||||
|
||||
[JsonProperty("callType")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
/// <summary>
|
||||
/// Gets or sets the CallType
|
||||
/// </summary>
|
||||
public eContactMethodCallType CallType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumeration of eContactMethodDevice values
|
||||
/// </summary>
|
||||
public enum eContactMethodDevice
|
||||
{
|
||||
Unknown = 0,
|
||||
Mobile,
|
||||
Other,
|
||||
Telephone,
|
||||
Video
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumeration of eContactMethodCallType values
|
||||
/// </summary>
|
||||
public enum eContactMethodCallType
|
||||
{
|
||||
Unknown = 0,
|
||||
Audio,
|
||||
Video
|
||||
}
|
||||
}
|
||||
@@ -1,339 +1,20 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
[Flags]
|
||||
/// <summary>
|
||||
/// Enumeration of eMeetingEventChangeType values
|
||||
/// </summary>
|
||||
public enum eMeetingEventChangeType
|
||||
{
|
||||
Unknown = 0,
|
||||
MeetingStartWarning = 1,
|
||||
MeetingStart = 2,
|
||||
MeetingEndWarning = 4,
|
||||
MeetingEnd = 8
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasScheduleAwareness
|
||||
/// </summary>
|
||||
public interface IHasScheduleAwareness
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the CodecScheduleAwareness instance
|
||||
/// </summary>
|
||||
CodecScheduleAwareness CodecSchedule { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Method to initiate getting the schedule from the server
|
||||
/// </summary>
|
||||
void GetSchedule();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a CodecScheduleAwareness
|
||||
/// </summary>
|
||||
public class CodecScheduleAwareness
|
||||
{
|
||||
List<Meeting> _meetings;
|
||||
|
||||
public event EventHandler<MeetingEventArgs> MeetingEventChange;
|
||||
|
||||
public event EventHandler<EventArgs> MeetingsListHasChanged;
|
||||
|
||||
private int _meetingWarningMinutes = 5;
|
||||
|
||||
//private Meeting _previousChangedMeeting;
|
||||
|
||||
//private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown;
|
||||
|
||||
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;
|
||||
MeetingsListHasChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
private readonly 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to fire MeetingEventChange. Should only fire once for each changeType on each meeting
|
||||
/// </summary>
|
||||
/// <param name="changeType"></param>
|
||||
/// <param name="meeting"></param>
|
||||
private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "*****************OnMeetingChange. id: {0} changeType: {1}**********************", meeting.Id, changeType);
|
||||
if (changeType != (changeType & meeting.NotifiedChangeTypes))
|
||||
{
|
||||
// Add this change type to the NotifiedChangeTypes
|
||||
meeting.NotifiedChangeTypes |= changeType;
|
||||
MeetingEventChange?.Invoke(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Meeting: {0} already notified of changeType: {1}", meeting.Id, changeType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks the schedule to see if any MeetingEventChange updates should be fired
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
private void CheckSchedule(object o)
|
||||
{
|
||||
// Iterate the meeting list and check if any meeting need to do anything
|
||||
|
||||
const double meetingTimeEpsilon = 0.05;
|
||||
foreach (var m in Meetings)
|
||||
{
|
||||
var changeType = eMeetingEventChangeType.Unknown;
|
||||
|
||||
if (eMeetingEventChangeType.MeetingStartWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStartWarning) && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds);
|
||||
changeType = eMeetingEventChangeType.MeetingStartWarning;
|
||||
}
|
||||
else if (eMeetingEventChangeType.MeetingStart != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStart) && Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStart");
|
||||
changeType = eMeetingEventChangeType.MeetingStart;
|
||||
}
|
||||
else if (eMeetingEventChangeType.MeetingEndWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEndWarning) && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEndWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingEnd.TotalMinutes, m.TimeToMeetingEnd.Seconds);
|
||||
changeType = eMeetingEventChangeType.MeetingEndWarning;
|
||||
}
|
||||
else if (eMeetingEventChangeType.MeetingEnd != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEnd) && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEnd");
|
||||
changeType = eMeetingEventChangeType.MeetingEnd;
|
||||
}
|
||||
|
||||
if (changeType != eMeetingEventChangeType.Unknown)
|
||||
{
|
||||
OnMeetingChange(changeType, m);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Meeting
|
||||
/// </summary>
|
||||
public class Meeting
|
||||
{
|
||||
[JsonProperty("minutesBeforeMeeting")]
|
||||
public int MinutesBeforeMeeting;
|
||||
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
[JsonProperty("organizer")]
|
||||
public string Organizer { get; set; }
|
||||
[JsonProperty("title")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Title
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
[JsonProperty("agenda")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Agenda
|
||||
/// </summary>
|
||||
public string Agenda { get; set; }
|
||||
|
||||
[JsonProperty("meetingWarningMinutes")]
|
||||
public TimeSpan MeetingWarningMinutes
|
||||
{
|
||||
get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); }
|
||||
}
|
||||
[JsonProperty("timeToMeetingStart")]
|
||||
public TimeSpan TimeToMeetingStart
|
||||
{
|
||||
get
|
||||
{
|
||||
return StartTime - DateTime.Now;
|
||||
}
|
||||
}
|
||||
[JsonProperty("timeToMeetingEnd")]
|
||||
public TimeSpan TimeToMeetingEnd
|
||||
{
|
||||
get
|
||||
{
|
||||
return EndTime - DateTime.Now;
|
||||
}
|
||||
}
|
||||
[JsonProperty("startTime")]
|
||||
/// <summary>
|
||||
/// Gets or sets the StartTime
|
||||
/// </summary>
|
||||
public DateTime StartTime { get; set; }
|
||||
[JsonProperty("endTime")]
|
||||
/// <summary>
|
||||
/// Gets or sets the EndTime
|
||||
/// </summary>
|
||||
public DateTime EndTime { get; set; }
|
||||
[JsonProperty("duration")]
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return EndTime - StartTime;
|
||||
}
|
||||
}
|
||||
[JsonProperty("privacy")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Privacy
|
||||
/// </summary>
|
||||
public eMeetingPrivacy Privacy { get; set; }
|
||||
[JsonProperty("joinable")]
|
||||
public bool Joinable
|
||||
{
|
||||
get
|
||||
{
|
||||
var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now
|
||||
&& DateTime.Now <= EndTime.AddSeconds(-_joinableCooldownSeconds);
|
||||
//Debug.LogMessage(LogEventLevel.Verbose, "Meeting Id: {0} joinable: {1}", Id, joinable);
|
||||
return joinable;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("dialable")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Dialable
|
||||
/// </summary>
|
||||
public bool Dialable { get; set; }
|
||||
|
||||
//public string ConferenceNumberToDial { get; set; }
|
||||
[JsonProperty("conferencePassword")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ConferencePassword
|
||||
/// </summary>
|
||||
public string ConferencePassword { get; set; }
|
||||
[JsonProperty("isOneButtonToPushMeeting")]
|
||||
/// <summary>
|
||||
/// Gets or sets the IsOneButtonToPushMeeting
|
||||
/// </summary>
|
||||
public bool IsOneButtonToPushMeeting { get; set; }
|
||||
|
||||
[JsonProperty("calls")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Calls
|
||||
/// </summary>
|
||||
public List<Call> Calls { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the change types that have already been notified for
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
/// <summary>
|
||||
/// Gets or sets the NotifiedChangeTypes
|
||||
/// </summary>
|
||||
public eMeetingEventChangeType NotifiedChangeTypes { get; set; }
|
||||
|
||||
[JsonIgnore] private readonly int _joinableCooldownSeconds;
|
||||
|
||||
|
||||
public Meeting()
|
||||
{
|
||||
Calls = new List<Call>();
|
||||
_joinableCooldownSeconds = 300;
|
||||
}
|
||||
|
||||
public Meeting(int joinableCooldownSeconds)
|
||||
{
|
||||
Calls = new List<Call>();
|
||||
_joinableCooldownSeconds = joinableCooldownSeconds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region Overrides of Object
|
||||
|
||||
/// <summary>
|
||||
/// ToString method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0}:{1}: {2}-{3}", Title, Agenda, StartTime, EndTime);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Call
|
||||
/// </summary>
|
||||
public class Call
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Number
|
||||
/// </summary>
|
||||
public string Number { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Protocol
|
||||
/// </summary>
|
||||
public string Protocol { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the CallRate
|
||||
/// </summary>
|
||||
public string CallRate { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the CallType
|
||||
/// </summary>
|
||||
public string CallType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a MeetingEventArgs
|
||||
/// </summary>
|
||||
public class MeetingEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ChangeType
|
||||
/// </summary>
|
||||
public eMeetingEventChangeType ChangeType { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Meeting
|
||||
/// </summary>
|
||||
public Meeting Meeting { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,61 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.DSP
|
||||
{
|
||||
public abstract class DspBase : EssentialsDevice, ILevelControls
|
||||
{
|
||||
public Dictionary<string,IBasicVolumeWithFeedback> LevelControlPoints { get; private set; }
|
||||
/// <summary>
|
||||
/// Base class for DSP devices
|
||||
/// </summary>
|
||||
public abstract class DspBase : EssentialsDevice, ILevelControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the collection of level control points
|
||||
/// </summary>
|
||||
public Dictionary<string, IBasicVolumeWithFeedback> LevelControlPoints { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of dialer control points
|
||||
/// </summary>
|
||||
public Dictionary<string, DspControlPoint> DialerControlPoints { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of switcher control points
|
||||
/// </summary>
|
||||
public Dictionary<string, DspControlPoint> SwitcherControlPoints { get; private set; }
|
||||
|
||||
public DspBase(string key, string name) :
|
||||
base(key, name)
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DspBase class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
public DspBase(string key, string name) :
|
||||
base(key, name)
|
||||
{
|
||||
|
||||
LevelControlPoints = new Dictionary<string, IBasicVolumeWithFeedback>();
|
||||
DialerControlPoints = new Dictionary<string, DspControlPoint>();
|
||||
SwitcherControlPoints = new Dictionary<string, DspControlPoint>();
|
||||
}
|
||||
LevelControlPoints = new Dictionary<string, IBasicVolumeWithFeedback>();
|
||||
DialerControlPoints = new Dictionary<string, DspControlPoint>();
|
||||
SwitcherControlPoints = new Dictionary<string, DspControlPoint>();
|
||||
}
|
||||
|
||||
|
||||
// in audio call feedback
|
||||
// in audio call feedback
|
||||
|
||||
// VOIP
|
||||
// Phone dialer
|
||||
// VOIP
|
||||
// Phone dialer
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Fusion
|
||||
// Privacy state
|
||||
// Online state
|
||||
// level/mutes ?
|
||||
|
||||
// AC Log call stats
|
||||
|
||||
// Typical presets:
|
||||
// call default preset to restore levels and mutes
|
||||
// Fusion
|
||||
// Privacy state
|
||||
// Online state
|
||||
// level/mutes ?
|
||||
|
||||
public abstract class DspControlPoint :IKeyed
|
||||
{
|
||||
// AC Log call stats
|
||||
|
||||
// Typical presets:
|
||||
// call default preset to restore levels and mutes
|
||||
|
||||
/// <summary>
|
||||
/// Base class for DSP control points
|
||||
/// </summary>
|
||||
public abstract class DspControlPoint : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Key
|
||||
/// </summary>
|
||||
public string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DspControlPoint class
|
||||
/// </summary>
|
||||
/// <param name="key">The control point key</param>
|
||||
protected DspControlPoint(string key) => Key = key;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class DspLevelControlPoint :DspControlPoint, IBasicVolumeWithFeedback
|
||||
/// <summary>
|
||||
/// Base class for DSP level control points with volume and mute functionality
|
||||
/// </summary>
|
||||
public abstract class DspLevelControlPoint : DspControlPoint, IBasicVolumeWithFeedback
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the MuteFeedback
|
||||
@@ -66,30 +89,63 @@ namespace PepperDash.Essentials.Devices.Common.DSP
|
||||
/// </summary>
|
||||
public IntFeedback VolumeLevelFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DspLevelControlPoint class
|
||||
/// </summary>
|
||||
/// <param name="key">The control point key</param>
|
||||
/// <param name="muteFeedbackFunc">Function to get mute status</param>
|
||||
/// <param name="volumeLevelFeedbackFunc">Function to get volume level</param>
|
||||
protected DspLevelControlPoint(string key, Func<bool> muteFeedbackFunc, Func<int> volumeLevelFeedbackFunc) : base(key)
|
||||
{
|
||||
MuteFeedback = new BoolFeedback(muteFeedbackFunc);
|
||||
VolumeLevelFeedback = new IntFeedback(volumeLevelFeedbackFunc);
|
||||
MuteFeedback = new BoolFeedback("mute", muteFeedbackFunc);
|
||||
VolumeLevelFeedback = new IntFeedback("volume", volumeLevelFeedbackFunc);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns mute off
|
||||
/// </summary>
|
||||
public abstract void MuteOff();
|
||||
/// <summary>
|
||||
/// Turns mute on
|
||||
/// </summary>
|
||||
public abstract void MuteOn();
|
||||
/// <summary>
|
||||
/// Toggles mute state
|
||||
/// </summary>
|
||||
public abstract void MuteToggle();
|
||||
/// <summary>
|
||||
/// Sets the volume level
|
||||
/// </summary>
|
||||
/// <param name="level">The volume level to set</param>
|
||||
public abstract void SetVolume(ushort level);
|
||||
/// <summary>
|
||||
/// Decreases volume
|
||||
/// </summary>
|
||||
/// <param name="pressRelease">True when pressed, false when released</param>
|
||||
public abstract void VolumeDown(bool pressRelease);
|
||||
/// <summary>
|
||||
/// Increases volume
|
||||
/// </summary>
|
||||
/// <param name="pressRelease">True when pressed, false when released</param>
|
||||
public abstract void VolumeUp(bool pressRelease);
|
||||
}
|
||||
|
||||
|
||||
public abstract class DspDialerBase:DspControlPoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for DSP dialer control points
|
||||
/// </summary>
|
||||
public abstract class DspDialerBase : DspControlPoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DspDialerBase class
|
||||
/// </summary>
|
||||
/// <param name="key">The dialer control point key</param>
|
||||
protected DspDialerBase(string key) : base(key) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Main program
|
||||
// VTC
|
||||
// ATC
|
||||
// Mics, unusual
|
||||
// Main program
|
||||
// VTC
|
||||
// ATC
|
||||
// Mics, unusual
|
||||
|
||||
}
|
||||
@@ -14,7 +14,9 @@ namespace PepperDash.Essentials.Devices.Common
|
||||
/// </summary>
|
||||
public class DeviceFactory
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DeviceFactory class
|
||||
/// </summary>
|
||||
public DeviceFactory()
|
||||
{
|
||||
var assy = Assembly.GetExecutingAssembly();
|
||||
|
||||
@@ -11,37 +11,53 @@ using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a BasicIrDisplay
|
||||
/// </summary>
|
||||
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced
|
||||
/// <summary>
|
||||
/// Represents a BasicIrDisplay
|
||||
/// </summary>
|
||||
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the IrPort
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the IrPort
|
||||
/// </summary>
|
||||
public IrOutputPortController IrPort { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the IrPulseTime
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the IrPulseTime
|
||||
/// </summary>
|
||||
public ushort IrPulseTime { get; set; }
|
||||
|
||||
protected Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
get { return () => _PowerIsOn; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the power is on feedback function
|
||||
/// </summary>
|
||||
protected Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
get { return () => _PowerIsOn; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the is cooling down feedback function
|
||||
/// </summary>
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||
{
|
||||
get { return () => _IsCoolingDown; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the is warming up feedback function
|
||||
/// </summary>
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc
|
||||
{
|
||||
get { return () => _IsWarmingUp; }
|
||||
}
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the BasicIrDisplay class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
/// <param name="port">The IR output port</param>
|
||||
/// <param name="irDriverFilepath">The path to the IR driver file</param>
|
||||
public BasicIrDisplay(string key, string name, IROutputPort port, string irDriverFilepath)
|
||||
: base(key, name)
|
||||
{
|
||||
@@ -53,74 +69,74 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
|
||||
InputPorts.AddRange(new RoutingPortCollection<RoutingInputPort>
|
||||
{
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi2), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi3), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi4), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Component1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Video1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Antenna), this, false),
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hdmi1 method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Hdmi1 method
|
||||
/// </summary>
|
||||
public void Hdmi1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_1, IrPulseTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hdmi2 method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Hdmi2 method
|
||||
/// </summary>
|
||||
public void Hdmi2()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_2, IrPulseTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hdmi3 method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Hdmi3 method
|
||||
/// </summary>
|
||||
public void Hdmi3()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_3, IrPulseTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hdmi4 method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Hdmi4 method
|
||||
/// </summary>
|
||||
public void Hdmi4()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_4, IrPulseTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Component1 method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Component1 method
|
||||
/// </summary>
|
||||
public void Component1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_COMPONENT_1, IrPulseTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Video1 method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Video1 method
|
||||
/// </summary>
|
||||
public void Video1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_VIDEO_1, IrPulseTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Antenna method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Antenna method
|
||||
/// </summary>
|
||||
public void Antenna()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_ANTENNA, IrPulseTime);
|
||||
@@ -128,31 +144,31 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
|
||||
#region IPower Members
|
||||
|
||||
/// <summary>
|
||||
/// PowerOn method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// PowerOn method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void PowerOn()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
|
||||
_PowerIsOn = true;
|
||||
_PowerIsOn = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PowerOff method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// PowerOff method
|
||||
/// </summary>
|
||||
public override void PowerOff()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
_PowerIsOn = false;
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PowerToggle method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// PowerToggle method
|
||||
/// </summary>
|
||||
public override void PowerToggle()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
_PowerIsOn = false;
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
|
||||
}
|
||||
|
||||
@@ -160,25 +176,25 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
|
||||
#region IBasicVolumeControls Members
|
||||
|
||||
/// <summary>
|
||||
/// VolumeUp method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// VolumeUp method
|
||||
/// </summary>
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_PLUS, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// VolumeDown method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// VolumeDown method
|
||||
/// </summary>
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_MINUS, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MuteToggle method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// MuteToggle method
|
||||
/// </summary>
|
||||
public void MuteToggle()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_MUTE, 200);
|
||||
@@ -190,7 +206,8 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
{
|
||||
_IsWarmingUp = true;
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
new CTimer(o => {
|
||||
new CTimer(o =>
|
||||
{
|
||||
_IsWarmingUp = false;
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
}, 10000);
|
||||
@@ -213,13 +230,13 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
/// Typically called by the discovery routing algorithm.
|
||||
/// </summary>
|
||||
/// <param name="inputSelector">A delegate containing the input selector method to call</param>
|
||||
/// <summary>
|
||||
/// ExecuteSwitch method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// ExecuteSwitch method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void ExecuteSwitch(object inputSelector)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Switching to input '{0}'", (inputSelector as Action).ToString());
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Switching to input '{0}'", (inputSelector as Action).ToString());
|
||||
|
||||
Action finishSwitch = () =>
|
||||
{
|
||||
@@ -246,42 +263,45 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// LinkToApi method
|
||||
/// </summary>
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
/// <summary>
|
||||
/// LinkToApi method
|
||||
/// </summary>
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a BasicIrDisplayFactory
|
||||
/// </summary>
|
||||
public class BasicIrDisplayFactory : EssentialsDeviceFactory<BasicIrDisplay>
|
||||
{
|
||||
public BasicIrDisplayFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "basicirdisplay" };
|
||||
}
|
||||
/// <summary>
|
||||
/// Represents a BasicIrDisplayFactory
|
||||
/// </summary>
|
||||
public class BasicIrDisplayFactory : EssentialsDeviceFactory<BasicIrDisplay>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the BasicIrDisplayFactory class
|
||||
/// </summary>
|
||||
public BasicIrDisplayFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "basicirdisplay" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BasicIrDisplay Device");
|
||||
var ir = IRPortHelper.GetIrPort(dc.Properties);
|
||||
if (ir != null)
|
||||
{
|
||||
var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName);
|
||||
display.IrPulseTime = 200; // Set default pulse time for IR commands.
|
||||
return display;
|
||||
}
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BasicIrDisplay Device");
|
||||
var ir = IRPortHelper.GetIrPort(dc.Properties);
|
||||
if (ir != null)
|
||||
{
|
||||
var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName);
|
||||
display.IrPulseTime = 200; // Set default pulse time for IR commands.
|
||||
return display;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,7 +19,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
/// Abstract base class for display devices that provides common display functionality
|
||||
/// including power control, input switching, and routing capabilities.
|
||||
/// </summary>
|
||||
public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources
|
||||
public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources, IHasFeedback
|
||||
{
|
||||
private RoutingInputPort _currentInputPort;
|
||||
|
||||
@@ -73,13 +73,11 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
handler?.Invoke(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
handler?.Invoke(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
@@ -160,6 +158,9 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
||||
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
||||
|
||||
Feedbacks.Add(IsCoolingDownFeedback);
|
||||
Feedbacks.Add(IsWarmingUpFeedback);
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
|
||||
CurrentSources = new Dictionary<eRoutingSignalType, SourceListItem>
|
||||
@@ -194,17 +195,8 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
/// Gets the collection of feedback objects for this display device.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public virtual FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FeedbackCollection<Feedback>
|
||||
{
|
||||
IsCoolingDownFeedback,
|
||||
IsWarmingUpFeedback
|
||||
};
|
||||
}
|
||||
}
|
||||
public virtual FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Executes a switch to the specified input on the display device. Must be implemented by derived classes.
|
||||
@@ -252,47 +244,35 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
/// <param name="joinMap">The join map configuration for the device.</param>
|
||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, DisplayControllerJoinMap joinMap)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.LogMessage(LogEventLevel.Information, "Linking to Display: {0}", displayDevice.Name);
|
||||
this.LogDebug("Linking to Trilist {ipId}", trilist.ID.ToString("X"));
|
||||
this.LogDebug("Linking to Display: {displayName}", displayDevice.Name);
|
||||
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
|
||||
|
||||
var commMonitor = displayDevice as ICommunicationMonitor;
|
||||
if (commMonitor != null)
|
||||
if (displayDevice is ICommunicationMonitor commMonitor)
|
||||
{
|
||||
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
}
|
||||
|
||||
// TODO: revisit this as there could be issues with this approach
|
||||
var inputNumber = 0;
|
||||
var inputKeys = new List<string>();
|
||||
|
||||
var inputNumberFeedback = new IntFeedback(() => inputNumber);
|
||||
var inputNumberFeedback = new IntFeedback("inputNumber", () => inputNumber);
|
||||
|
||||
// Two way feedbacks
|
||||
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
|
||||
// Add input number feedback to the device feedback collection to keep it around...
|
||||
Feedbacks.Add(inputNumberFeedback);
|
||||
|
||||
if (twoWayDisplay != null)
|
||||
// Two way feedbacks
|
||||
if (displayDevice is TwoWayDisplayBase twoWayDisplay)
|
||||
{
|
||||
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
|
||||
|
||||
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Information, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
|
||||
|
||||
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => this.LogDebug("CurrentInputFeedback_OutputChange {input}", a.StringValue);
|
||||
|
||||
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
|
||||
}
|
||||
|
||||
// Power Off
|
||||
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOff();
|
||||
});
|
||||
|
||||
var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase;
|
||||
if (twoWayDisplayDevice != null)
|
||||
{
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
twoWayDisplay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!a.BoolValue)
|
||||
{
|
||||
@@ -307,10 +287,18 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
}
|
||||
};
|
||||
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
|
||||
twoWayDisplay.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
|
||||
twoWayDisplay.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
|
||||
}
|
||||
|
||||
// Power Off
|
||||
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOff();
|
||||
});
|
||||
|
||||
// PowerOn
|
||||
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
|
||||
{
|
||||
@@ -320,44 +308,61 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
});
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
|
||||
{
|
||||
if (i < joinMap.InputNamesOffset.JoinSpan)
|
||||
var localindex = i;
|
||||
if (localindex >= joinMap.InputNamesOffset.JoinSpan)
|
||||
{
|
||||
inputKeys.Add(displayDevice.InputPorts[i].Key);
|
||||
var tempKey = inputKeys.ElementAt(i);
|
||||
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
|
||||
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
|
||||
Debug.LogMessage(LogEventLevel.Verbose, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
|
||||
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
|
||||
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
|
||||
this.LogWarning("Device has {inputCount} inputs. The Join Map allows up to {joinSpan} inputs. Discarding inputs {discardStart} - {discardEnd} from bridge.",
|
||||
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, localindex + 1, displayDevice.InputPorts.Count);
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
Debug.LogMessage(LogEventLevel.Information, displayDevice, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
|
||||
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
|
||||
{
|
||||
inputKeys.Add(displayDevice.InputPorts[localindex].Key);
|
||||
|
||||
var tempKey = inputKeys.ElementAt(localindex);
|
||||
|
||||
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + localindex), () => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
|
||||
|
||||
this.LogDebug("Setting Input Select Action on Digital Join {joinNumber} to Input: {input}", joinMap.InputSelectOffset.JoinNumber + localindex, displayDevice.InputPorts[tempKey].Key);
|
||||
|
||||
trilist.SetString((uint)(joinMap.InputNamesOffset.JoinNumber + localindex), displayDevice.InputPorts[localindex].Key);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
|
||||
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
|
||||
this.LogDebug("Setting Input Select Action on Analog Join {inputSelectJoin}", joinMap.InputSelect);
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (requestedInput) =>
|
||||
{
|
||||
if (a == 0)
|
||||
if (requestedInput == 0)
|
||||
{
|
||||
displayDevice.PowerOff();
|
||||
inputNumber = 0;
|
||||
return;
|
||||
}
|
||||
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
|
||||
|
||||
// using 1-based indexing for inputs coming from SIMPL, so need to check if the input is <= the count, not <
|
||||
if (requestedInput > 0 && requestedInput <= displayDevice.InputPorts.Count && requestedInput != inputNumber)
|
||||
{
|
||||
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
|
||||
inputNumber = a;
|
||||
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(requestedInput - 1).Selector);
|
||||
|
||||
inputNumber = requestedInput;
|
||||
|
||||
return;
|
||||
}
|
||||
else if (a == 102)
|
||||
|
||||
if (requestedInput == 102)
|
||||
{
|
||||
displayDevice.PowerToggle();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (displayDevice is TwoWayDisplayBase)
|
||||
{
|
||||
inputNumberFeedback?.FireUpdate();
|
||||
}
|
||||
if (twoWayDisplay != null)
|
||||
inputNumberFeedback.FireUpdate();
|
||||
});
|
||||
|
||||
|
||||
@@ -430,95 +435,4 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract base class for two-way display devices that provide feedback capabilities.
|
||||
/// Extends DisplayBase with routing feedback and power control feedback functionality.
|
||||
/// </summary>
|
||||
public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets feedback for the current input selection on the display.
|
||||
/// </summary>
|
||||
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Abstract function that must be implemented by derived classes to provide the current input feedback value.
|
||||
/// Must be implemented by concrete sub-classes.
|
||||
/// </summary>
|
||||
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets feedback indicating whether the display is currently powered on.
|
||||
/// </summary>
|
||||
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Abstract function that must be implemented by derived classes to provide the power state feedback value.
|
||||
/// Must be implemented by concrete sub-classes.
|
||||
/// </summary>
|
||||
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default mock display instance for testing and development purposes.
|
||||
/// </summary>
|
||||
public static MockDisplay DefaultDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DefaultDisplay == null)
|
||||
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||
return _DefaultDisplay;
|
||||
}
|
||||
}
|
||||
static MockDisplay _DefaultDisplay;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the TwoWayDisplayBase class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key identifier for this display device.</param>
|
||||
/// <param name="name">The friendly name for this display device.</param>
|
||||
public TwoWayDisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
||||
|
||||
WarmupTime = 7000;
|
||||
CooldownTime = 15000;
|
||||
|
||||
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||
|
||||
Feedbacks.Add(CurrentInputFeedback);
|
||||
Feedbacks.Add(PowerIsOnFeedback);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||
|
||||
}
|
||||
|
||||
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (UsageTracker != null)
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue)
|
||||
UsageTracker.StartDeviceUsage();
|
||||
else
|
||||
UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when a numeric switch change occurs on the display.
|
||||
/// </summary>
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
protected void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IInputHdmi1
|
||||
/// </summary>
|
||||
public interface IInputHdmi1 { void InputHdmi1(); }
|
||||
[Obsolete()]
|
||||
public interface IInputHdmi1
|
||||
{
|
||||
/// <summary>
|
||||
/// Switches to HDMI 1 input
|
||||
/// </summary>
|
||||
void InputHdmi1();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IInputHdmi2
|
||||
/// </summary>
|
||||
public interface IInputHdmi2 { void InputHdmi2(); }
|
||||
[Obsolete()]
|
||||
public interface IInputHdmi2
|
||||
{
|
||||
/// <summary>
|
||||
/// Switches to HDMI 2 input
|
||||
/// </summary>
|
||||
void InputHdmi2();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IInputHdmi3
|
||||
/// </summary>
|
||||
public interface IInputHdmi3 { void InputHdmi3(); }
|
||||
[Obsolete()]
|
||||
public interface IInputHdmi3
|
||||
{
|
||||
/// <summary>
|
||||
/// Switches to HDMI 3 input
|
||||
/// </summary>
|
||||
void InputHdmi3();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IInputHdmi4
|
||||
/// </summary>
|
||||
public interface IInputHdmi4 { void InputHdmi4(); }
|
||||
[Obsolete()]
|
||||
public interface IInputHdmi4
|
||||
{
|
||||
/// <summary>
|
||||
/// Switches to HDMI 4 input
|
||||
/// </summary>
|
||||
void InputHdmi4();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IInputDisplayPort1
|
||||
/// </summary>
|
||||
public interface IInputDisplayPort1 { void InputDisplayPort1(); }
|
||||
[Obsolete()]
|
||||
public interface IInputDisplayPort1
|
||||
{
|
||||
/// <summary>
|
||||
/// Switches to DisplayPort 1 input
|
||||
/// </summary>
|
||||
void InputDisplayPort1();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IInputDisplayPort2
|
||||
/// </summary>
|
||||
public interface IInputDisplayPort2 { void InputDisplayPort2(); }
|
||||
[Obsolete()]
|
||||
public interface IInputDisplayPort2
|
||||
{
|
||||
/// <summary>
|
||||
/// Switches to DisplayPort 2 input
|
||||
/// </summary>
|
||||
void InputDisplayPort2();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IInputVga1
|
||||
/// </summary>
|
||||
public interface IInputVga1 { void InputVga1(); }
|
||||
[Obsolete()]
|
||||
public interface IInputVga1
|
||||
{
|
||||
/// <summary>
|
||||
/// Switches to VGA 1 input
|
||||
/// </summary>
|
||||
void InputVga1();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,16 +16,19 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
/// Represents a MockDisplay
|
||||
/// </summary>
|
||||
public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs<string>, IRoutingSinkWithSwitchingWithInputPort, IHasPowerControlWithFeedback
|
||||
{
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Inputs
|
||||
/// </summary>
|
||||
public ISelectableItems<string> Inputs { get; private set; }
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the power is on feedback function
|
||||
/// </summary>
|
||||
protected override Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
get
|
||||
@@ -34,8 +37,12 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
{
|
||||
return _PowerIsOn;
|
||||
};
|
||||
} }
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the is cooling down feedback function
|
||||
/// </summary>
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -45,7 +52,10 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
};
|
||||
}
|
||||
}
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc
|
||||
/// <summary>
|
||||
/// Gets the is warming up feedback function
|
||||
/// </summary>
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -55,120 +65,128 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the current input feedback function
|
||||
/// </summary>
|
||||
protected override Func<string> CurrentInputFeedbackFunc { get { return () => Inputs.CurrentItem; } }
|
||||
|
||||
int VolumeHeldRepeatInterval = 200;
|
||||
ushort VolumeInterval = 655;
|
||||
ushort _FakeVolumeLevel = 31768;
|
||||
bool _IsMuted;
|
||||
ushort _FakeVolumeLevel = 31768;
|
||||
bool _IsMuted;
|
||||
|
||||
public MockDisplay(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the MockDisplay class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
public MockDisplay(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
Inputs = new MockDisplayInputs
|
||||
{
|
||||
Items = new Dictionary<string, ISelectableItem>
|
||||
{
|
||||
{ "HDMI1", new MockDisplayInput ( "HDMI1", "HDMI 1",this ) },
|
||||
{ "HDMI2", new MockDisplayInput ("HDMI2", "HDMI 2",this ) },
|
||||
{ "HDMI3", new MockDisplayInput ("HDMI3", "HDMI 3",this ) },
|
||||
{ "HDMI4", new MockDisplayInput ("HDMI4", "HDMI 4",this )},
|
||||
{ "DP", new MockDisplayInput ("DP", "DisplayPort", this ) }
|
||||
}
|
||||
{
|
||||
{ "HDMI1", new MockDisplayInput ( "HDMI1", "HDMI 1",this ) },
|
||||
{ "HDMI2", new MockDisplayInput ("HDMI2", "HDMI 2",this ) },
|
||||
{ "HDMI3", new MockDisplayInput ("HDMI3", "HDMI 3",this ) },
|
||||
{ "HDMI4", new MockDisplayInput ("HDMI4", "HDMI 4",this )},
|
||||
{ "DP", new MockDisplayInput ("DP", "DisplayPort", this ) }
|
||||
}
|
||||
};
|
||||
|
||||
Inputs.CurrentItemChanged += (o, a) => CurrentInputFeedback.FireUpdate();
|
||||
|
||||
var hdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, "HDMI1", this);
|
||||
var hdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, "HDMI2", this);
|
||||
var hdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, "HDMI3", this);
|
||||
var hdmiIn4 = new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, "HDMI4", this);
|
||||
var dpIn = new RoutingInputPort(RoutingPortNames.DisplayPortIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.DisplayPort, "DP", this);
|
||||
InputPorts.AddRange(new[] { hdmiIn1, hdmiIn2, hdmiIn3, hdmiIn4, dpIn });
|
||||
Inputs.CurrentItemChanged += (o, a) => CurrentInputFeedback.FireUpdate();
|
||||
|
||||
VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
|
||||
MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted);
|
||||
var hdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, "HDMI1", this);
|
||||
var hdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, "HDMI2", this);
|
||||
var hdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, "HDMI3", this);
|
||||
var hdmiIn4 = new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, "HDMI4", this);
|
||||
var dpIn = new RoutingInputPort(RoutingPortNames.DisplayPortIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.DisplayPort, "DP", this);
|
||||
InputPorts.AddRange(new[] { hdmiIn1, hdmiIn2, hdmiIn3, hdmiIn4, dpIn });
|
||||
|
||||
VolumeLevelFeedback = new IntFeedback("volume", () => { return _FakeVolumeLevel; });
|
||||
MuteFeedback = new BoolFeedback("muteOn", () => _IsMuted);
|
||||
|
||||
WarmupTime = 10000;
|
||||
CooldownTime = 10000;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PowerOn method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void PowerOn()
|
||||
{
|
||||
if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||
{
|
||||
_IsWarmingUp = true;
|
||||
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||
// Fake power-up cycle
|
||||
WarmupTimer = new CTimer(o =>
|
||||
{
|
||||
_IsWarmingUp = false;
|
||||
_PowerIsOn = true;
|
||||
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||
PowerIsOnFeedback.InvokeFireUpdate();
|
||||
}, WarmupTime);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// PowerOn method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void PowerOn()
|
||||
{
|
||||
if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||
{
|
||||
_IsWarmingUp = true;
|
||||
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||
// Fake power-up cycle
|
||||
WarmupTimer = new CTimer(o =>
|
||||
{
|
||||
_IsWarmingUp = false;
|
||||
_PowerIsOn = true;
|
||||
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||
PowerIsOnFeedback.InvokeFireUpdate();
|
||||
}, WarmupTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PowerOff method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void PowerOff()
|
||||
{
|
||||
// If a display has unreliable-power off feedback, just override this and
|
||||
// remove this check.
|
||||
if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||
{
|
||||
_IsCoolingDown = true;
|
||||
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||
// Fake cool-down cycle
|
||||
CooldownTimer = new CTimer(o =>
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Cooldown timer ending", this);
|
||||
_IsCoolingDown = false;
|
||||
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||
/// <summary>
|
||||
/// PowerOff method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void PowerOff()
|
||||
{
|
||||
// If a display has unreliable-power off feedback, just override this and
|
||||
// remove this check.
|
||||
if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||
{
|
||||
_IsCoolingDown = true;
|
||||
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||
// Fake cool-down cycle
|
||||
CooldownTimer = new CTimer(o =>
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Cooldown timer ending", this);
|
||||
_IsCoolingDown = false;
|
||||
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.InvokeFireUpdate();
|
||||
}, CooldownTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PowerToggle method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void PowerToggle()
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
|
||||
PowerOff();
|
||||
else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
|
||||
PowerOn();
|
||||
}
|
||||
}, CooldownTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ExecuteSwitch method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void ExecuteSwitch(object selector)
|
||||
{
|
||||
/// <summary>
|
||||
/// PowerToggle method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void PowerToggle()
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
|
||||
PowerOff();
|
||||
else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
|
||||
PowerOn();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ExecuteSwitch method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void ExecuteSwitch(object selector)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "ExecuteSwitch: {0}", this, selector);
|
||||
|
||||
if (!_PowerIsOn)
|
||||
{
|
||||
PowerOn();
|
||||
}
|
||||
if (!_PowerIsOn)
|
||||
{
|
||||
PowerOn();
|
||||
}
|
||||
|
||||
if (!Inputs.Items.TryGetValue(selector.ToString(), out var input))
|
||||
return;
|
||||
@@ -184,13 +202,14 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
|
||||
if (inputPort == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Unable to find input port for selector {selector}", this, selector);
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Unable to find input port for selector {selector}", this, selector);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Setting current input port to {inputPort}", this, inputPort);
|
||||
CurrentInputPort = inputPort;
|
||||
} catch (Exception ex)
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Error making switch: {Exception}", this, ex);
|
||||
}
|
||||
@@ -201,14 +220,14 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
/// </summary>
|
||||
public void SetInput(string selector)
|
||||
{
|
||||
ISelectableItem currentInput = null;
|
||||
ISelectableItem currentInput = null;
|
||||
|
||||
try
|
||||
{
|
||||
currentInput = Inputs.Items.SingleOrDefault(Inputs => Inputs.Value.IsSelected).Value;
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
currentInput = Inputs.Items.SingleOrDefault(Inputs => Inputs.Value.IsSelected).Value;
|
||||
}
|
||||
catch { }
|
||||
|
||||
|
||||
if (currentInput != null)
|
||||
{
|
||||
@@ -216,12 +235,12 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
currentInput.IsSelected = false;
|
||||
}
|
||||
|
||||
if (!Inputs.Items.TryGetValue(selector, out var input))
|
||||
if (!Inputs.Items.TryGetValue(selector, out var input))
|
||||
return;
|
||||
|
||||
input.IsSelected = true;
|
||||
input.IsSelected = true;
|
||||
|
||||
Inputs.CurrentItem = selector;
|
||||
Inputs.CurrentItem = selector;
|
||||
}
|
||||
|
||||
|
||||
@@ -232,37 +251,37 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
/// </summary>
|
||||
public IntFeedback VolumeLevelFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// SetVolume method
|
||||
/// </summary>
|
||||
public void SetVolume(ushort level)
|
||||
{
|
||||
_FakeVolumeLevel = level;
|
||||
VolumeLevelFeedback.InvokeFireUpdate();
|
||||
}
|
||||
/// <summary>
|
||||
/// SetVolume method
|
||||
/// </summary>
|
||||
public void SetVolume(ushort level)
|
||||
{
|
||||
_FakeVolumeLevel = level;
|
||||
VolumeLevelFeedback.InvokeFireUpdate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MuteOn method
|
||||
/// </summary>
|
||||
public void MuteOn()
|
||||
{
|
||||
_IsMuted = true;
|
||||
MuteFeedback.InvokeFireUpdate();
|
||||
}
|
||||
/// <summary>
|
||||
/// MuteOn method
|
||||
/// </summary>
|
||||
public void MuteOn()
|
||||
{
|
||||
_IsMuted = true;
|
||||
MuteFeedback.InvokeFireUpdate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MuteOff method
|
||||
/// </summary>
|
||||
public void MuteOff()
|
||||
{
|
||||
_IsMuted = false;
|
||||
MuteFeedback.InvokeFireUpdate();
|
||||
}
|
||||
/// <summary>
|
||||
/// MuteOff method
|
||||
/// </summary>
|
||||
public void MuteOff()
|
||||
{
|
||||
_IsMuted = false;
|
||||
MuteFeedback.InvokeFireUpdate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the MuteFeedback
|
||||
/// </summary>
|
||||
public BoolFeedback MuteFeedback { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the MuteFeedback
|
||||
/// </summary>
|
||||
public BoolFeedback MuteFeedback { get; private set; }
|
||||
|
||||
|
||||
#endregion
|
||||
@@ -273,74 +292,77 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
/// VolumeUp method
|
||||
/// </summary>
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
{
|
||||
//while (pressRelease)
|
||||
//{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Down {0}", pressRelease);
|
||||
if (pressRelease)
|
||||
{
|
||||
var newLevel = _FakeVolumeLevel + VolumeInterval;
|
||||
SetVolume((ushort)newLevel);
|
||||
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
||||
}
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Down {0}", pressRelease);
|
||||
if (pressRelease)
|
||||
{
|
||||
var newLevel = _FakeVolumeLevel + VolumeInterval;
|
||||
SetVolume((ushort)newLevel);
|
||||
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// VolumeDown method
|
||||
/// </summary>
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
/// <summary>
|
||||
/// VolumeDown method
|
||||
/// </summary>
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
//while (pressRelease)
|
||||
//{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Up {0}", pressRelease);
|
||||
if (pressRelease)
|
||||
{
|
||||
var newLevel = _FakeVolumeLevel - VolumeInterval;
|
||||
SetVolume((ushort)newLevel);
|
||||
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
||||
}
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Up {0}", pressRelease);
|
||||
if (pressRelease)
|
||||
{
|
||||
var newLevel = _FakeVolumeLevel - VolumeInterval;
|
||||
SetVolume((ushort)newLevel);
|
||||
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MuteToggle method
|
||||
/// </summary>
|
||||
public void MuteToggle()
|
||||
{
|
||||
_IsMuted = !_IsMuted;
|
||||
MuteFeedback.InvokeFireUpdate();
|
||||
}
|
||||
/// <summary>
|
||||
/// MuteToggle method
|
||||
/// </summary>
|
||||
public void MuteToggle()
|
||||
{
|
||||
_IsMuted = !_IsMuted;
|
||||
MuteFeedback.InvokeFireUpdate();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// LinkToApi method
|
||||
/// </summary>
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
/// <summary>
|
||||
/// LinkToApi method
|
||||
/// </summary>
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a MockDisplayFactory
|
||||
/// </summary>
|
||||
public class MockDisplayFactory : EssentialsDeviceFactory<MockDisplay>
|
||||
{
|
||||
public MockDisplayFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "mockdisplay" , "mockdisplay2" };
|
||||
}
|
||||
/// <summary>
|
||||
/// Represents a MockDisplayFactory
|
||||
/// </summary>
|
||||
public class MockDisplayFactory : EssentialsDeviceFactory<MockDisplay>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the MockDisplayFactory class
|
||||
/// </summary>
|
||||
public MockDisplayFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "mockdisplay", "mockdisplay2" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Mock Display Device");
|
||||
return new MockDisplay(dc.Key, dc.Name);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Mock Display Device");
|
||||
return new MockDisplay(dc.Key, dc.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,6 @@
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
{
|
||||
@@ -15,6 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
{
|
||||
private Dictionary<string, ISelectableItem> _items;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of selectable items
|
||||
/// </summary>
|
||||
public Dictionary<string, ISelectableItem> Items
|
||||
{
|
||||
get
|
||||
@@ -34,8 +33,11 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
|
||||
private string _currentItem;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the currently selected item
|
||||
/// </summary>
|
||||
public string CurrentItem
|
||||
{
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentItem;
|
||||
@@ -51,7 +53,13 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the items collection is updated
|
||||
/// </summary>
|
||||
public event EventHandler ItemsUpdated;
|
||||
/// <summary>
|
||||
/// Occurs when the current item changes
|
||||
/// </summary>
|
||||
public event EventHandler CurrentItemChanged;
|
||||
}
|
||||
|
||||
@@ -63,7 +71,10 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
private MockDisplay _parent;
|
||||
|
||||
private bool _isSelected;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this input is selected
|
||||
/// </summary>
|
||||
public bool IsSelected
|
||||
{
|
||||
get
|
||||
@@ -91,8 +102,17 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
/// </summary>
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when this item is updated
|
||||
/// </summary>
|
||||
public event EventHandler ItemUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the MockDisplayInput class
|
||||
/// </summary>
|
||||
/// <param name="key">The input key</param>
|
||||
/// <param name="name">The input name</param>
|
||||
/// <param name="parent">The parent mock display</param>
|
||||
public MockDisplayInput(string key, string name, MockDisplay parent)
|
||||
{
|
||||
Key = key;
|
||||
@@ -107,7 +127,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
{
|
||||
if (!_parent.PowerIsOnFeedback.BoolValue) _parent.PowerOn();
|
||||
|
||||
foreach(var input in _parent.Inputs.Items)
|
||||
foreach (var input in _parent.Inputs.Items)
|
||||
{
|
||||
input.Value.IsSelected = input.Key == this.Key;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.CrestronIO;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Devices.Common;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
@@ -28,6 +25,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
ISwitchedOutput LowerRelay;
|
||||
ISwitchedOutput LatchedRelay;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the InUpPosition
|
||||
/// </summary>
|
||||
public bool InUpPosition
|
||||
{
|
||||
get { return _isInUpPosition; }
|
||||
@@ -41,10 +41,12 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
}
|
||||
|
||||
private bool _isInUpPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Type
|
||||
/// </summary>
|
||||
public eScreenLiftControlType Type { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Mode
|
||||
/// </summary>
|
||||
@@ -54,13 +56,20 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
/// Gets or sets the DisplayDeviceKey
|
||||
/// </summary>
|
||||
public string DisplayDeviceKey { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the IsInUpPosition
|
||||
/// </summary>
|
||||
public BoolFeedback IsInUpPosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event that fires when the position changes
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> PositionChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for ScreenLiftController
|
||||
/// </summary>
|
||||
public ScreenLiftController(string key, string name, ScreenLiftControllerConfigProperties config)
|
||||
: base(key, name)
|
||||
{
|
||||
@@ -69,7 +78,7 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
Mode = Config.Mode;
|
||||
Type = Config.Type;
|
||||
|
||||
IsInUpPosition = new BoolFeedback(() => _isInUpPosition);
|
||||
IsInUpPosition = new BoolFeedback("isInUpPosition", () => _isInUpPosition);
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
@@ -206,14 +215,14 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
/// <summary>
|
||||
/// Attempts to get the port on teh specified device from config
|
||||
/// </summary>
|
||||
/// <param name="relayConfig"></param>
|
||||
/// <param name="relayKey"></param>
|
||||
/// <returns></returns>
|
||||
ISwitchedOutput GetSwitchedOutputFromDevice(string relayKey)
|
||||
{
|
||||
var portDevice = DeviceManager.GetDeviceForKey(relayKey);
|
||||
if (portDevice != null)
|
||||
{
|
||||
return (portDevice as ISwitchedOutput);
|
||||
return portDevice as ISwitchedOutput;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -238,58 +247,14 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a ScreenLiftControllerConfigProperties
|
||||
/// </summary>
|
||||
public class ScreenLiftControllerConfigProperties
|
||||
{
|
||||
[JsonProperty("displayDeviceKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the DisplayDeviceKey
|
||||
/// </summary>
|
||||
public string DisplayDeviceKey { get; set; }
|
||||
|
||||
[JsonProperty("type")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
/// <summary>
|
||||
/// Gets or sets the Type
|
||||
/// </summary>
|
||||
public eScreenLiftControlType Type { get; set; }
|
||||
|
||||
[JsonProperty("mode")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
/// <summary>
|
||||
/// Gets or sets the Mode
|
||||
/// </summary>
|
||||
public eScreenLiftControlMode Mode { get; set; }
|
||||
|
||||
[JsonProperty("relays")]
|
||||
public Dictionary<string,ScreenLiftRelaysConfig> Relays { get; set; }
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Represents a ScreenLiftRelaysConfig
|
||||
/// </summary>
|
||||
public class ScreenLiftRelaysConfig
|
||||
{
|
||||
[JsonProperty("deviceKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the DeviceKey
|
||||
/// </summary>
|
||||
public string DeviceKey { get; set; }
|
||||
|
||||
[JsonProperty("pulseTimeInMs")]
|
||||
/// <summary>
|
||||
/// Gets or sets the PulseTimeInMs
|
||||
/// </summary>
|
||||
public int PulseTimeInMs { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a ScreenLiftControllerFactory
|
||||
/// </summary>
|
||||
public class ScreenLiftControllerFactory : EssentialsDeviceFactory<RelayControlledShade>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for ScreenLiftControllerFactory
|
||||
/// </summary>
|
||||
public ScreenLiftControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "screenliftcontroller" };
|
||||
@@ -307,13 +272,4 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
return new ScreenLiftController(dc.Key, dc.Name, props);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumeration of eScreenLiftControlMode values
|
||||
/// </summary>
|
||||
public enum eScreenLiftControlMode
|
||||
{
|
||||
momentary,
|
||||
latched
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a ScreenLiftControllerConfigProperties
|
||||
/// </summary>
|
||||
public class ScreenLiftControllerConfigProperties
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the DisplayDeviceKey
|
||||
/// </summary>
|
||||
[JsonProperty("displayDeviceKey")]
|
||||
public string DisplayDeviceKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Type
|
||||
/// </summary>
|
||||
[JsonProperty("type")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eScreenLiftControlType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Mode
|
||||
/// </summary>
|
||||
[JsonProperty("mode")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public eScreenLiftControlMode Mode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Relays
|
||||
/// </summary>
|
||||
[JsonProperty("relays")]
|
||||
public Dictionary<string, ScreenLiftRelaysConfig> Relays { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a ScreenLiftRelaysConfig
|
||||
/// </summary>
|
||||
public class ScreenLiftRelaysConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the DeviceKey
|
||||
/// </summary>
|
||||
[JsonProperty("deviceKey")]
|
||||
public string DeviceKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the PulseTimeInMs
|
||||
/// </summary>
|
||||
[JsonProperty("pulseTimeInMs")]
|
||||
public int PulseTimeInMs { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract base class for two-way display devices that provide feedback capabilities.
|
||||
/// Extends DisplayBase with routing feedback and power control feedback functionality.
|
||||
/// </summary>
|
||||
public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets feedback for the current input selection on the display.
|
||||
/// </summary>
|
||||
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Abstract function that must be implemented by derived classes to provide the current input feedback value.
|
||||
/// Must be implemented by concrete sub-classes.
|
||||
/// </summary>
|
||||
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets feedback indicating whether the display is currently powered on.
|
||||
/// </summary>
|
||||
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Abstract function that must be implemented by derived classes to provide the power state feedback value.
|
||||
/// Must be implemented by concrete sub-classes.
|
||||
/// </summary>
|
||||
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default mock display instance for testing and development purposes.
|
||||
/// </summary>
|
||||
public static MockDisplay DefaultDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DefaultDisplay == null)
|
||||
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||
return _DefaultDisplay;
|
||||
}
|
||||
}
|
||||
static MockDisplay _DefaultDisplay;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the TwoWayDisplayBase class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key identifier for this display device.</param>
|
||||
/// <param name="name">The friendly name for this display device.</param>
|
||||
public TwoWayDisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
CurrentInputFeedback = new StringFeedback("currentInput", CurrentInputFeedbackFunc);
|
||||
|
||||
WarmupTime = 7000;
|
||||
CooldownTime = 15000;
|
||||
|
||||
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||
|
||||
Feedbacks.Add(CurrentInputFeedback);
|
||||
Feedbacks.Add(PowerIsOnFeedback);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||
|
||||
}
|
||||
|
||||
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (UsageTracker != null)
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue)
|
||||
UsageTracker.StartDeviceUsage();
|
||||
else
|
||||
UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when a numeric switch change occurs on the display.
|
||||
/// </summary>
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
protected void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
NumericSwitchChange?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration of eScreenLiftControlMode values
|
||||
/// </summary>
|
||||
public enum eScreenLiftControlMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Momentary control mode for screen lift
|
||||
/// </summary>
|
||||
momentary,
|
||||
/// <summary>
|
||||
/// Latched control mode for screen lift
|
||||
/// </summary>
|
||||
latched
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
using PepperDash.Core;
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Generic
|
||||
{
|
||||
@@ -12,11 +11,16 @@ namespace PepperDash.Essentials.Devices.Common.Generic
|
||||
/// </summary>
|
||||
public class GenericSink : EssentialsDevice, IRoutingSinkWithInputPort
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the GenericSink class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
public GenericSink(string key, string name) : base(key, name)
|
||||
{
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
|
||||
var inputPort = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
|
||||
var inputPort = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
|
||||
|
||||
InputPorts.Add(inputPort);
|
||||
}
|
||||
@@ -35,10 +39,12 @@ namespace PepperDash.Essentials.Devices.Common.Generic
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentSourceInfo
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo {
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get => _currentSource;
|
||||
set {
|
||||
if(value == _currentSource)
|
||||
set
|
||||
{
|
||||
if (value == _currentSource)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -51,8 +57,14 @@ namespace PepperDash.Essentials.Devices.Common.Generic
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current input port
|
||||
/// </summary>
|
||||
public RoutingInputPort CurrentInputPort => InputPorts[0];
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the current source changes
|
||||
/// </summary>
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
}
|
||||
|
||||
@@ -61,6 +73,9 @@ namespace PepperDash.Essentials.Devices.Common.Generic
|
||||
/// </summary>
|
||||
public class GenericSinkFactory : EssentialsDeviceFactory<GenericSink>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the GenericSinkFactory class
|
||||
/// </summary>
|
||||
public GenericSinkFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "genericsink", "genericdestination" };
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
@@ -13,38 +7,43 @@ using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a GenericSource
|
||||
/// </summary>
|
||||
public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IUsageTracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a GenericSource
|
||||
/// </summary>
|
||||
public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IUsageTracking
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the DisplayUiType
|
||||
/// </summary>
|
||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } }
|
||||
/// <summary>
|
||||
/// Gets or sets the DisplayUiType
|
||||
/// </summary>
|
||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the GenericSource class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
public GenericSource(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
: base(key, name)
|
||||
{
|
||||
|
||||
AnyOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { AnyOut };
|
||||
}
|
||||
AnyOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { AnyOut };
|
||||
}
|
||||
|
||||
#region IRoutingOutputs Members
|
||||
#region IRoutingOutputs Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the AnyOut
|
||||
/// </summary>
|
||||
public RoutingOutputPort AnyOut { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputPorts
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the AnyOut
|
||||
/// </summary>
|
||||
public RoutingOutputPort AnyOut { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputPorts
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IUsageTracking Members
|
||||
|
||||
@@ -54,13 +53,16 @@ namespace PepperDash.Essentials.Devices.Common
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a GenericSourceFactory
|
||||
/// </summary>
|
||||
public class GenericSourceFactory : EssentialsDeviceFactory<GenericSource>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the GenericSourceFactory class
|
||||
/// </summary>
|
||||
public GenericSourceFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "genericsource" };
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
@@ -16,134 +13,165 @@ using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Lighting
|
||||
{
|
||||
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
|
||||
{
|
||||
#region ILightingScenes Members
|
||||
|
||||
public event EventHandler<LightingSceneChangeEventArgs> LightingSceneChange;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the LightingScenes
|
||||
/// </summary>
|
||||
public List<LightingScene> LightingScenes { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentLightingScene
|
||||
/// </summary>
|
||||
public LightingScene CurrentLightingScene { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentLightingSceneFeedback
|
||||
/// Base class for lighting devices that support scenes
|
||||
/// </summary>
|
||||
public IntFeedback CurrentLightingSceneFeedback { get; protected set; }
|
||||
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
|
||||
{
|
||||
#region ILightingScenes Members
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Event fired when lighting scene changes
|
||||
/// </summary>
|
||||
public event EventHandler<LightingSceneChangeEventArgs> LightingSceneChange;
|
||||
|
||||
protected LightingBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
LightingScenes = new List<LightingScene>();
|
||||
/// <summary>
|
||||
/// Gets or sets the LightingScenes
|
||||
/// </summary>
|
||||
public List<LightingScene> LightingScenes { get; protected set; }
|
||||
|
||||
CurrentLightingScene = new LightingScene();
|
||||
//CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); });
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentLightingScene
|
||||
/// </summary>
|
||||
public LightingScene CurrentLightingScene { get; protected set; }
|
||||
|
||||
public abstract void SelectScene(LightingScene scene);
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentLightingSceneFeedback
|
||||
/// </summary>
|
||||
public IntFeedback CurrentLightingSceneFeedback { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// SimulateSceneSelect method
|
||||
/// </summary>
|
||||
public void SimulateSceneSelect(string sceneName)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Simulating selection of scene '{0}'", sceneName);
|
||||
#endregion
|
||||
|
||||
var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName));
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LightingBase class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
protected LightingBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
LightingScenes = new List<LightingScene>();
|
||||
|
||||
if (scene != null)
|
||||
{
|
||||
CurrentLightingScene = scene;
|
||||
OnLightingSceneChange();
|
||||
}
|
||||
}
|
||||
CurrentLightingScene = new LightingScene();
|
||||
//CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the IsActive property on each scene and fires the LightingSceneChange event
|
||||
/// </summary>
|
||||
protected void OnLightingSceneChange()
|
||||
{
|
||||
foreach (var scene in LightingScenes)
|
||||
{
|
||||
if (scene == CurrentLightingScene)
|
||||
scene.IsActive = true;
|
||||
|
||||
else
|
||||
scene.IsActive = false;
|
||||
}
|
||||
LightingSceneChange?.Invoke(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
|
||||
}
|
||||
/// <summary>
|
||||
/// Selects the specified lighting scene
|
||||
/// </summary>
|
||||
/// <param name="scene">The lighting scene to select</param>
|
||||
public abstract void SelectScene(LightingScene scene);
|
||||
|
||||
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
|
||||
string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new GenericLightingJoinMap(joinStart);
|
||||
/// <summary>
|
||||
/// SimulateSceneSelect method
|
||||
/// </summary>
|
||||
public void SimulateSceneSelect(string sceneName)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Simulating selection of scene '{0}'", sceneName);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName));
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
return LinkLightingToApi(lightingDevice, trilist, joinMap);
|
||||
}
|
||||
|
||||
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap)
|
||||
if (scene != null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
CurrentLightingScene = scene;
|
||||
OnLightingSceneChange();
|
||||
}
|
||||
}
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
|
||||
/// <summary>
|
||||
/// Sets the IsActive property on each scene and fires the LightingSceneChange event
|
||||
/// </summary>
|
||||
protected void OnLightingSceneChange()
|
||||
{
|
||||
foreach (var scene in LightingScenes)
|
||||
{
|
||||
if (scene == CurrentLightingScene)
|
||||
scene.IsActive = true;
|
||||
|
||||
// GenericLighitng Actions & FeedBack
|
||||
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
|
||||
else
|
||||
scene.IsActive = false;
|
||||
}
|
||||
LightingSceneChange?.Invoke(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
|
||||
}
|
||||
|
||||
var sceneIndex = 0;
|
||||
/// <summary>
|
||||
/// Links the lighting device to API with join map configuration
|
||||
/// </summary>
|
||||
/// <param name="lightingDevice">The lighting device to link</param>
|
||||
/// <param name="trilist">The trilist to link to</param>
|
||||
/// <param name="joinStart">The starting join number</param>
|
||||
/// <param name="joinMapKey">The join map key</param>
|
||||
/// <param name="bridge">The EISC API bridge</param>
|
||||
/// <returns>The configured join map</returns>
|
||||
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
|
||||
string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new GenericLightingJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
return LinkLightingToApi(lightingDevice, trilist, joinMap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Links the lighting device to API using an existing join map
|
||||
/// </summary>
|
||||
/// <param name="lightingDevice">The lighting device to link</param>
|
||||
/// <param name="trilist">The trilist to link to</param>
|
||||
/// <param name="joinMap">The join map to use</param>
|
||||
/// <returns>The join map used for linking</returns>
|
||||
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
|
||||
|
||||
// GenericLighitng Actions & FeedBack
|
||||
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
|
||||
|
||||
var sceneIndex = 0;
|
||||
foreach (var scene in lightingDevice.LightingScenes)
|
||||
{
|
||||
var index = sceneIndex;
|
||||
|
||||
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + index), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[index]));
|
||||
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)]);
|
||||
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
|
||||
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
|
||||
|
||||
sceneIndex++;
|
||||
}
|
||||
|
||||
trilist.OnlineStatusChange += (sender, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
|
||||
sceneIndex = 0;
|
||||
foreach (var scene in lightingDevice.LightingScenes)
|
||||
{
|
||||
var index = sceneIndex;
|
||||
|
||||
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + index), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[index]));
|
||||
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)]);
|
||||
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
|
||||
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
|
||||
scene.IsActiveFeedback.FireUpdate();
|
||||
|
||||
sceneIndex++;
|
||||
}
|
||||
};
|
||||
|
||||
trilist.OnlineStatusChange += (sender, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
|
||||
sceneIndex = 0;
|
||||
foreach (var scene in lightingDevice.LightingScenes)
|
||||
{
|
||||
var index = sceneIndex;
|
||||
|
||||
trilist.StringInput[(uint) (joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
|
||||
trilist.BooleanInput[(uint) (joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
|
||||
scene.IsActiveFeedback.FireUpdate();
|
||||
|
||||
sceneIndex++;
|
||||
}
|
||||
};
|
||||
|
||||
return joinMap;
|
||||
}
|
||||
return joinMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,20 @@ namespace PepperDash.Essentials.Devices.Common.Room
|
||||
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IHasDefaultDisplay, IHasCurrentVolumeControls, IRoomOccupancy,
|
||||
IEmergency, IMicrophonePrivacy
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets whether to exclude this room from global functions
|
||||
/// </summary>
|
||||
bool ExcludeFromGlobalFunctions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Runs the route action for the given routeKey and sourceListKey
|
||||
/// </summary>
|
||||
/// <param name="routeKey">The route key</param>
|
||||
void RunRouteAction(string routeKey);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PropertiesConfig
|
||||
/// </summary>
|
||||
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
|
||||
}
|
||||
}
|
||||
@@ -12,18 +12,40 @@ namespace PepperDash.Essentials.Devices.Common.Room
|
||||
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback,
|
||||
IRoomOccupancy, IEmergency, IMicrophonePrivacy
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the PropertiesConfig
|
||||
/// </summary>
|
||||
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether to exclude this room from global functions
|
||||
/// </summary>
|
||||
bool ExcludeFromGlobalFunctions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Runs the route action for the given routeKey and sourceListKey
|
||||
/// </summary>
|
||||
/// <param name="routeKey">The route key</param>
|
||||
void RunRouteAction(string routeKey);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ScheduleSource
|
||||
/// </summary>
|
||||
IHasScheduleAwareness ScheduleSource { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the InCallFeedback
|
||||
/// </summary>
|
||||
new BoolFeedback InCallFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PrivacyModeIsOnFeedback
|
||||
/// </summary>
|
||||
new BoolFeedback PrivacyModeIsOnFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DefaultCodecRouteString
|
||||
/// </summary>
|
||||
string DefaultCodecRouteString { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Room
|
||||
{
|
||||
@@ -12,6 +7,9 @@ namespace PepperDash.Essentials.Devices.Common.Room
|
||||
/// </summary>
|
||||
public interface IEssentialsRoomPropertiesConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the PropertiesConfig
|
||||
/// </summary>
|
||||
EssentialsRoomPropertiesConfig PropertiesConfig { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Devices.Common.Displays;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using System.Collections.Generic;
|
||||
using TwoWayDisplayBase = PepperDash.Essentials.Devices.Common.Displays.TwoWayDisplayBase;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Room
|
||||
@@ -11,15 +11,31 @@ namespace PepperDash.Essentials.Devices.Common.Room
|
||||
/// <summary>
|
||||
/// Defines the contract for IEssentialsTechRoom
|
||||
/// </summary>
|
||||
public interface IEssentialsTechRoom:IEssentialsRoom, ITvPresetsProvider,IBridgeAdvanced,IRunDirectRouteAction
|
||||
public interface IEssentialsTechRoom : IEssentialsRoom, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the PropertiesConfig
|
||||
/// </summary>
|
||||
EssentialsTechRoomConfig PropertiesConfig { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Tuners
|
||||
/// </summary>
|
||||
Dictionary<string, IRSetTopBoxBase> Tuners { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Displays
|
||||
/// </summary>
|
||||
Dictionary<string, TwoWayDisplayBase> Displays { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Powers on the room
|
||||
/// </summary>
|
||||
void RoomPowerOn();
|
||||
|
||||
/// <summary>
|
||||
/// Powers off the room
|
||||
/// </summary>
|
||||
void RoomPowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a IRSetTopBoxBaseFactory
|
||||
/// </summary>
|
||||
public class IRSetTopBoxBaseFactory : EssentialsDeviceFactory<IRSetTopBoxBase>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IRSetTopBoxBaseFactory"/> class
|
||||
/// </summary>
|
||||
public IRSetTopBoxBaseFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "settopbox" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new SetTopBox Device");
|
||||
var irCont = IRPortHelper.GetIrOutputPortController(dc);
|
||||
var config = dc.Properties.ToObject<SetTopBoxPropertiesConfig>();
|
||||
var stb = new IRSetTopBoxBase(dc.Key, dc.Name, irCont, config);
|
||||
|
||||
var listName = dc.Properties.Value<string>("presetsList");
|
||||
if (listName != null)
|
||||
stb.LoadPresets(listName);
|
||||
return stb;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common
|
||||
{
|
||||
|
||||
@@ -27,6 +27,12 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
/// </summary>
|
||||
public string StopOrPresetButtonLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RelayControlledShade class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
/// <param name="config">The relay controlled shade configuration</param>
|
||||
public RelayControlledShade(string key, string name, RelayControlledShadeConfigProperties config)
|
||||
: base(key, name)
|
||||
{
|
||||
@@ -157,6 +163,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
/// </summary>
|
||||
public class RelayControlledShadeFactory : EssentialsDeviceFactory<RelayControlledShade>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RelayControlledShadeFactory class
|
||||
/// </summary>
|
||||
public RelayControlledShadeFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "relaycontrolledshade" };
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
using PepperDash.Essentials.Core.Shades;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Shades;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for shade devices
|
||||
/// </summary>
|
||||
public abstract class ShadeBase : EssentialsDevice, IShadesOpenCloseStop
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ShadeBase class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
public ShadeBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
@@ -13,8 +21,17 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
|
||||
#region iShadesOpenClose Members
|
||||
|
||||
/// <summary>
|
||||
/// Opens the shade
|
||||
/// </summary>
|
||||
public abstract void Open();
|
||||
/// <summary>
|
||||
/// Stops the shade
|
||||
/// </summary>
|
||||
public abstract void Stop();
|
||||
/// <summary>
|
||||
/// Closes the shade
|
||||
/// </summary>
|
||||
public abstract void Close();
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -14,8 +14,17 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
{
|
||||
ShadeControllerConfigProperties Config;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of shades controlled by this controller
|
||||
/// </summary>
|
||||
public List<IShadesOpenCloseStop> Shades { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ShadeController class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
/// <param name="config">The shade controller configuration</param>
|
||||
public ShadeController(string key, string name, ShadeControllerConfigProperties config)
|
||||
: base(key, name)
|
||||
{
|
||||
@@ -76,6 +85,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
||||
/// </summary>
|
||||
public class ShadeControllerFactory : EssentialsDeviceFactory<ShadeController>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ShadeControllerFactory class
|
||||
/// </summary>
|
||||
public ShadeControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "shadecontroller" };
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
@@ -22,6 +21,9 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
/// </summary>
|
||||
public RoutingInputPort AnyVideoIn { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the CurrentInputPort
|
||||
/// </summary>
|
||||
public RoutingInputPort CurrentInputPort => AnyVideoIn;
|
||||
|
||||
#region IRoutingInputs Members
|
||||
@@ -33,6 +35,11 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BlueJeansPc"/> class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
public BlueJeansPc(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
@@ -177,30 +184,12 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the current source changes
|
||||
/// </summary>
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a BlueJeansPcFactory
|
||||
/// </summary>
|
||||
public class BlueJeansPcFactory : EssentialsDeviceFactory<BlueJeansPc>
|
||||
{
|
||||
public BlueJeansPcFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "bluejeanspc" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BlueJeansPc Device");
|
||||
return new SoftCodec.BlueJeansPc(dc.Key, dc.Name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a BlueJeansPcFactory
|
||||
/// </summary>
|
||||
public class BlueJeansPcFactory : EssentialsDeviceFactory<BlueJeansPc>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BlueJeansPcFactory"/> class
|
||||
/// </summary>
|
||||
public BlueJeansPcFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "bluejeanspc" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BlueJeansPc Device");
|
||||
return new BlueJeansPc(dc.Key, dc.Name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
{
|
||||
@@ -18,7 +15,8 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentInputPort
|
||||
/// </summary>
|
||||
public RoutingInputPort CurrentInputPort {
|
||||
public RoutingInputPort CurrentInputPort
|
||||
{
|
||||
get => _currentInputPort;
|
||||
set
|
||||
{
|
||||
@@ -28,19 +26,25 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GenericSoftCodec"/> class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
/// <param name="props">The device properties</param>
|
||||
public GenericSoftCodec(string key, string name, GenericSoftCodecProperties props) : base(key, name)
|
||||
{
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
|
||||
for(var i = 1; i <= props.OutputCount; i++)
|
||||
for (var i = 1; i <= props.OutputCount; i++)
|
||||
{
|
||||
var outputPort = new RoutingOutputPort($"output{i}", eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
|
||||
|
||||
OutputPorts.Add(outputPort);
|
||||
}
|
||||
|
||||
for(var i = 1; i<= props.ContentInputCount; i++)
|
||||
for (var i = 1; i <= props.ContentInputCount; i++)
|
||||
{
|
||||
var inputPort = new RoutingInputPort($"contentInput{i}", eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, $"contentInput{i}", this);
|
||||
|
||||
@@ -52,7 +56,7 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
return;
|
||||
}
|
||||
|
||||
for(var i = 1; i <=props.CameraInputCount; i++)
|
||||
for (var i = 1; i <= props.CameraInputCount; i++)
|
||||
{
|
||||
var cameraPort = new RoutingInputPort($"cameraInput{i}", eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, $"cameraInput{i}", this);
|
||||
|
||||
@@ -72,7 +76,11 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentSourceInfoKey
|
||||
/// </summary>
|
||||
public string CurrentSourceInfoKey { get ; set; }
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentSourceInfo
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
@@ -97,7 +105,14 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the current source changes
|
||||
/// </summary>
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the input changes
|
||||
/// </summary>
|
||||
public event InputChangedEventHandler InputChanged;
|
||||
|
||||
/// <summary>
|
||||
@@ -107,7 +122,7 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
{
|
||||
var inputPort = InputPorts.FirstOrDefault(p => p.Selector == inputSelector);
|
||||
|
||||
if(inputPort == null)
|
||||
if (inputPort == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "No input port found for selector {inputSelector}", inputSelector);
|
||||
return;
|
||||
@@ -116,58 +131,4 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
CurrentInputPort = inputPort;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a GenericSoftCodecProperties
|
||||
/// </summary>
|
||||
public class GenericSoftCodecProperties
|
||||
{
|
||||
[JsonProperty("hasCameraInputs")]
|
||||
/// <summary>
|
||||
/// Gets or sets the HasCameraInputs
|
||||
/// </summary>
|
||||
public bool HasCameraInputs { get; set; }
|
||||
|
||||
[JsonProperty("cameraInputCount")]
|
||||
/// <summary>
|
||||
/// Gets or sets the CameraInputCount
|
||||
/// </summary>
|
||||
public int CameraInputCount { get; set; }
|
||||
|
||||
[JsonProperty("contentInputCount")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ContentInputCount
|
||||
/// </summary>
|
||||
public int ContentInputCount { get; set; }
|
||||
|
||||
[JsonProperty("contentOutputCount")]
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputCount
|
||||
/// </summary>
|
||||
public int OutputCount { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a GenericSoftCodecFactory
|
||||
/// </summary>
|
||||
public class GenericSoftCodecFactory: EssentialsDeviceFactory<GenericSoftCodec>
|
||||
{
|
||||
public GenericSoftCodecFactory()
|
||||
{
|
||||
TypeNames = new List<string> { "genericsoftcodec" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Attempting to create new Generic SoftCodec Device");
|
||||
|
||||
var props = dc.Properties.ToObject<GenericSoftCodecProperties>();
|
||||
|
||||
return new GenericSoftCodec(dc.Key, dc.Name, props);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a GenericSoftCodecFactory
|
||||
/// </summary>
|
||||
public class GenericSoftCodecFactory : EssentialsDeviceFactory<GenericSoftCodec>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GenericSoftCodecFactory"/> class
|
||||
/// </summary>
|
||||
public GenericSoftCodecFactory()
|
||||
{
|
||||
TypeNames = new List<string> { "genericsoftcodec" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Attempting to create new Generic SoftCodec Device");
|
||||
|
||||
var props = dc.Properties.ToObject<GenericSoftCodecProperties>();
|
||||
|
||||
return new GenericSoftCodec(dc.Key, dc.Name, props);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.SoftCodec
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a GenericSoftCodecProperties
|
||||
/// </summary>
|
||||
public class GenericSoftCodecProperties
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the HasCameraInputs
|
||||
/// </summary>
|
||||
[JsonProperty("hasCameraInputs")]
|
||||
public bool HasCameraInputs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CameraInputCount
|
||||
/// </summary>
|
||||
[JsonProperty("cameraInputCount")]
|
||||
public int CameraInputCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ContentInputCount
|
||||
/// </summary>
|
||||
[JsonProperty("contentInputCount")]
|
||||
public int ContentInputCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputCount
|
||||
/// </summary>
|
||||
[JsonProperty("contentOutputCount")]
|
||||
public int OutputCount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,71 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Sources
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a InRoomPc
|
||||
/// </summary>
|
||||
public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the DisplayUiType
|
||||
/// </summary>
|
||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
|
||||
/// <summary>
|
||||
/// Gets or sets the IconName
|
||||
/// </summary>
|
||||
public string IconName { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the HasPowerOnFeedback
|
||||
/// </summary>
|
||||
public BoolFeedback HasPowerOnFeedback { get; private set; }
|
||||
/// <summary>
|
||||
/// Represents a InRoomPc
|
||||
/// </summary>
|
||||
public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the DisplayUiType
|
||||
/// </summary>
|
||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
|
||||
/// <summary>
|
||||
/// Gets or sets the IconName
|
||||
/// </summary>
|
||||
public string IconName { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the HasPowerOnFeedback
|
||||
/// </summary>
|
||||
public BoolFeedback HasPowerOnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the AnyVideoOut
|
||||
/// </summary>
|
||||
public RoutingOutputPort AnyVideoOut { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the AnyVideoOut
|
||||
/// </summary>
|
||||
public RoutingOutputPort AnyVideoOut { get; private set; }
|
||||
|
||||
#region IRoutingOutputs Members
|
||||
#region IRoutingOutputs Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputPorts
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputPorts
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
public InRoomPc(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
IconName = "PC";
|
||||
HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback",
|
||||
() => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus);
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
OutputPorts.Add(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.None, 0, this));
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InRoomPc"/> class
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="name"></param>
|
||||
public InRoomPc(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
IconName = "PC";
|
||||
HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback",
|
||||
() => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus);
|
||||
|
||||
#region IHasFeedback Members
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>
|
||||
{
|
||||
(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.None, 0, this))
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Passes through the VideoStatuses list
|
||||
/// </summary>
|
||||
#region IHasFeedback Members
|
||||
|
||||
/// <summary>
|
||||
/// Passes through the VideoStatuses list
|
||||
/// </summary>
|
||||
public FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
get
|
||||
{
|
||||
var newList = new FeedbackCollection<Feedback>();
|
||||
newList.AddRange(this.GetVideoStatuses().ToList());
|
||||
return newList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IUsageTracking Members
|
||||
|
||||
@@ -75,27 +78,6 @@ namespace PepperDash.Essentials.Devices.Common.Sources
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a InRoomPcFactory
|
||||
/// </summary>
|
||||
public class InRoomPcFactory : EssentialsDeviceFactory<InRoomPc>
|
||||
{
|
||||
public InRoomPcFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "inroompc" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new InRoomPc Device");
|
||||
return new InRoomPc(dc.Key, dc.Name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Sources
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a InRoomPcFactory
|
||||
/// </summary>
|
||||
public class InRoomPcFactory : EssentialsDeviceFactory<InRoomPc>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InRoomPcFactory"/> class
|
||||
/// </summary>
|
||||
public InRoomPcFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "inroompc" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new InRoomPc Device");
|
||||
return new InRoomPc(dc.Key, dc.Name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Sources
|
||||
{
|
||||
@@ -11,54 +6,59 @@ namespace PepperDash.Essentials.Devices.Common.Sources
|
||||
/// Represents a Laptop
|
||||
/// </summary>
|
||||
public class Laptop : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the DisplayUiType
|
||||
/// </summary>
|
||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
|
||||
/// <summary>
|
||||
/// Gets or sets the IconName
|
||||
/// </summary>
|
||||
public string IconName { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the HasPowerOnFeedback
|
||||
/// </summary>
|
||||
public BoolFeedback HasPowerOnFeedback { get; private set; }
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the DisplayUiType
|
||||
/// </summary>
|
||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
|
||||
/// <summary>
|
||||
/// Gets or sets the IconName
|
||||
/// </summary>
|
||||
public string IconName { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the HasPowerOnFeedback
|
||||
/// </summary>
|
||||
public BoolFeedback HasPowerOnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the AnyVideoOut
|
||||
/// </summary>
|
||||
public RoutingOutputPort AnyVideoOut { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the AnyVideoOut
|
||||
/// </summary>
|
||||
public RoutingOutputPort AnyVideoOut { get; private set; }
|
||||
|
||||
#region IRoutingOutputs Members
|
||||
#region IRoutingOutputs Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputPorts
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputPorts
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
public Laptop(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
IconName = "Laptop";
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Laptop class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
public Laptop(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
IconName = "Laptop";
|
||||
|
||||
HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback",
|
||||
() => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus);
|
||||
HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback",
|
||||
() => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus);
|
||||
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>
|
||||
{
|
||||
(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.None, 0, this))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#region IHasFeedback Members
|
||||
#region IHasFeedback Members
|
||||
|
||||
/// <summary>
|
||||
/// Passes through the VideoStatuses list
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Passes through the VideoStatuses list
|
||||
/// </summary>
|
||||
public FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
@@ -69,7 +69,7 @@ namespace PepperDash.Essentials.Devices.Common.Sources
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IUsageTracking Members
|
||||
|
||||
@@ -79,26 +79,5 @@ namespace PepperDash.Essentials.Devices.Common.Sources
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a LaptopFactory
|
||||
/// </summary>
|
||||
public class LaptopFactory : EssentialsDeviceFactory<Laptop>
|
||||
{
|
||||
public LaptopFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "laptop" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Laptop Device");
|
||||
return new Laptop(dc.Key, dc.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Sources
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a LaptopFactory
|
||||
/// </summary>
|
||||
public class LaptopFactory : EssentialsDeviceFactory<Laptop>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LaptopFactory"/> class
|
||||
/// </summary>
|
||||
public LaptopFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "laptop" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Laptop Device");
|
||||
return new Laptop(dc.Key, dc.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +1,63 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a AppleTV
|
||||
/// Wrapper class for an IR-Controlled AppleTV
|
||||
/// </summary>
|
||||
[Description("Wrapper class for an IR-Controlled AppleTV")]
|
||||
/// <summary>
|
||||
/// Represents a AppleTV
|
||||
/// </summary>
|
||||
public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource, IRoutingOutputs
|
||||
public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource, IRoutingOutputs
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the IrPort
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the IrPort
|
||||
/// </summary>
|
||||
public IrOutputPortController IrPort { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Standard Driver Name
|
||||
/// </summary>
|
||||
public const string StandardDriverName = "Apple_AppleTV_4th_Gen_Essentials.ir";
|
||||
/// <summary>
|
||||
/// Gets or sets the DisplayUiType
|
||||
/// </summary>
|
||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeAppleTv; } }
|
||||
/// <summary>
|
||||
/// Gets or sets the DisplayUiType
|
||||
/// </summary>
|
||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeAppleTv; } }
|
||||
|
||||
public AppleTV(string key, string name, IrOutputPortController portCont)
|
||||
: base(key, name)
|
||||
{
|
||||
IrPort = portCont;
|
||||
DeviceManager.AddDevice(portCont);
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AppleTV"/> class
|
||||
/// </summary>
|
||||
/// <param name="key">The device key</param>
|
||||
/// <param name="name">The device name</param>
|
||||
/// <param name="portCont">The IR output port controller</param>
|
||||
public AppleTV(string key, string name, IrOutputPortController portCont)
|
||||
: base(key, name)
|
||||
{
|
||||
IrPort = portCont;
|
||||
DeviceManager.AddDevice(portCont);
|
||||
|
||||
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio,
|
||||
eRoutingPortConnectionType.DigitalAudio, null, this);
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { HdmiOut, AnyAudioOut };
|
||||
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio,
|
||||
eRoutingPortConnectionType.DigitalAudio, null, this);
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { HdmiOut, AnyAudioOut };
|
||||
|
||||
PrintExpectedIrCommands();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PrintExpectedIrCommands method
|
||||
/// </summary>
|
||||
public void PrintExpectedIrCommands()
|
||||
{
|
||||
var cmds = typeof (AppleTvIrCommands).GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||
var cmds = typeof(AppleTvIrCommands).GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||
|
||||
foreach (var value in cmds.Select(cmd => cmd.GetValue(null)).OfType<string>())
|
||||
{
|
||||
@@ -64,151 +67,158 @@ namespace PepperDash.Essentials.Devices.Common
|
||||
|
||||
#region IDPad Members
|
||||
|
||||
/// <summary>
|
||||
/// Up method
|
||||
/// </summary>
|
||||
public void Up(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Up, pressRelease);
|
||||
}
|
||||
/// <summary>
|
||||
/// Up method
|
||||
/// </summary>
|
||||
public void Up(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Up, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Down method
|
||||
/// </summary>
|
||||
public void Down(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Down, pressRelease);
|
||||
}
|
||||
/// <summary>
|
||||
/// Down method
|
||||
/// </summary>
|
||||
public void Down(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Down, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Left method
|
||||
/// </summary>
|
||||
public void Left(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Left, pressRelease);
|
||||
}
|
||||
/// <summary>
|
||||
/// Left method
|
||||
/// </summary>
|
||||
public void Left(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Left, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Right method
|
||||
/// </summary>
|
||||
public void Right(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Right, pressRelease);
|
||||
}
|
||||
/// <summary>
|
||||
/// Right method
|
||||
/// </summary>
|
||||
public void Right(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Right, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Select method
|
||||
/// </summary>
|
||||
public void Select(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Enter, pressRelease);
|
||||
}
|
||||
/// <summary>
|
||||
/// Select method
|
||||
/// </summary>
|
||||
public void Select(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Enter, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Menu method
|
||||
/// </summary>
|
||||
public void Menu(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Menu, pressRelease);
|
||||
}
|
||||
/// <summary>
|
||||
/// Menu method
|
||||
/// </summary>
|
||||
public void Menu(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.Menu, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exit method
|
||||
/// </summary>
|
||||
public void Exit(bool pressRelease)
|
||||
{
|
||||
/// <summary>
|
||||
/// Exit method
|
||||
/// </summary>
|
||||
public void Exit(bool pressRelease)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region ITransport Members
|
||||
#region ITransport Members
|
||||
|
||||
/// <summary>
|
||||
/// Play method
|
||||
/// </summary>
|
||||
public void Play(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.PlayPause, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pause method
|
||||
/// </summary>
|
||||
public void Pause(bool pressRelease)
|
||||
{
|
||||
/// <summary>
|
||||
/// Play method
|
||||
/// </summary>
|
||||
public void Play(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.PlayPause, pressRelease);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
/// <summary>
|
||||
/// Rewind method
|
||||
/// </summary>
|
||||
public void Rewind(bool pressRelease)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Pause method
|
||||
/// </summary>
|
||||
public void Pause(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(AppleTvIrCommands.PlayPause, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void FFwd(bool pressRelease)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
/// <summary>
|
||||
/// Rewind method
|
||||
/// </summary>
|
||||
public void Rewind(bool pressRelease)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void ChapMinus(bool pressRelease)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void FFwd(bool pressRelease)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void ChapPlus(bool pressRelease)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void ChapMinus(bool pressRelease)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void Stop(bool pressRelease)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void ChapPlus(bool pressRelease)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void Record(bool pressRelease)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void Stop(bool pressRelease)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void Record(bool pressRelease)
|
||||
{
|
||||
}
|
||||
|
||||
#region IRoutingOutputs Members
|
||||
#endregion
|
||||
|
||||
public RoutingOutputPort HdmiOut { get; private set; }
|
||||
public RoutingOutputPort AnyAudioOut { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputPorts
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
#region IRoutingOutputs Members
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Gets the HdmiOut
|
||||
/// </summary>
|
||||
public RoutingOutputPort HdmiOut { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// LinkToApi method
|
||||
/// </summary>
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the AnyAudioOut
|
||||
/// </summary>
|
||||
public RoutingOutputPort AnyAudioOut { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputPorts
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// LinkToApi method
|
||||
/// </summary>
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new AppleTvJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
@@ -235,42 +245,6 @@ namespace PepperDash.Essentials.Devices.Common
|
||||
trilist.SetBoolSigAction(joinMap.Select.JoinNumber, Select);
|
||||
trilist.SetBoolSigAction(joinMap.Menu.JoinNumber, Menu);
|
||||
trilist.SetBoolSigAction(joinMap.PlayPause.JoinNumber, Play);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a AppleTVFactory
|
||||
/// </summary>
|
||||
public class AppleTVFactory : EssentialsDeviceFactory<AppleTV>
|
||||
{
|
||||
public AppleTVFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "appletv" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new AppleTV Device");
|
||||
var irCont = IRPortHelper.GetIrOutputPortController(dc);
|
||||
return new AppleTV(dc.Key, dc.Name, irCont);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AppleTvIrCommands
|
||||
{
|
||||
|
||||
public static string Up = "+";
|
||||
public static string Down = "-";
|
||||
public static string Left = IROutputStandardCommands.IROut_TRACK_MINUS;
|
||||
public static string Right = IROutputStandardCommands.IROut_TRACK_PLUS;
|
||||
public static string Enter = IROutputStandardCommands.IROut_ENTER;
|
||||
public static string PlayPause = "PLAY/PAUSE";
|
||||
public static string Rewind = "REWIND";
|
||||
public static string Menu = "Menu";
|
||||
public static string FastForward = "FASTFORWARD";
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user