mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-21 16:34:48 +00:00
Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f44040e4f | ||
|
|
10399a1be8 | ||
|
|
5409db193c | ||
|
|
f1ce54a524 | ||
|
|
dab5484d6e | ||
|
|
5c35a3be45 | ||
|
|
6cb98e12fa | ||
|
|
608601990b | ||
|
|
3e0f318f7f | ||
|
|
98d0cc8fdc | ||
|
|
c557c6cdd6 | ||
|
|
8525134ae7 | ||
|
|
1197b15a33 | ||
|
|
ea6a7568fc | ||
|
|
3a2a059ce1 | ||
|
|
f9d9df9d5c | ||
|
|
c284c4275f | ||
|
|
0418f8a7cc | ||
|
|
a5d409e93a | ||
|
|
59944c0e2f | ||
|
|
419177ccd5 | ||
|
|
bd01e2bacc | ||
|
|
2928c5cf94 | ||
|
|
82b5dc96c1 | ||
|
|
37cea8a11c | ||
|
|
a3f0901fa0 | ||
|
|
f91f435768 | ||
|
|
5120b2b574 | ||
|
|
7c90027578 | ||
|
|
bb694b4200 | ||
|
|
087d0a1149 | ||
|
|
4747c16b02 | ||
|
|
aa4d241dde | ||
|
|
9fc5586531 | ||
|
|
d33fd56529 | ||
|
|
8fc4d21f02 | ||
|
|
6d93662b31 | ||
|
|
11b190e76f | ||
|
|
df03a71cbc | ||
|
|
72e67a1c4c | ||
|
|
f8728b6825 | ||
|
|
d9ef8a2289 | ||
|
|
278408a3bc | ||
|
|
fd70377c7f | ||
|
|
06341b14f3 | ||
|
|
d7f9c74b2f | ||
|
|
5921b5dbb0 | ||
|
|
ba0de5128f | ||
|
|
b0a090062f | ||
|
|
9c0cab8218 | ||
|
|
c0af637108 | ||
|
|
9c9eaea928 | ||
|
|
9de94bd65f | ||
|
|
ff46fb8f29 | ||
|
|
d9243def30 | ||
|
|
258699fbcd | ||
|
|
738504e9fc | ||
|
|
cae1bbd6e6 | ||
|
|
dea4407e3e | ||
|
|
ab08a546f7 | ||
|
|
ef98d47792 | ||
|
|
c05976ee60 | ||
|
|
4ca1031bef | ||
|
|
6d61c4525e | ||
|
|
3db274ace5 |
@@ -23,23 +23,32 @@
|
||||
<FileName>$(TargetDir)$(TargetName).$(Version).$(TargetFramework).cpz</FileName>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="DeleteCLZ" BeforeTargets="PreBuildEvent" Condition="$(ProjectType) == 'Library' And $(TargetDir) != '' And Exists($(FileName))">
|
||||
<Delete Files="$(TargetDir)$(TargetName).$(Version).$(TargetFramework).clz">
|
||||
<Target Name="DeleteCLZ" BeforeTargets="CoreBuild" Condition="$(ProjectType) == 'Library' And $(TargetDir) != ''">
|
||||
<ItemGroup>
|
||||
<OldCLZFiles Include="$(TargetDir)$(TargetName).*.$(TargetFramework).clz" />
|
||||
</ItemGroup>
|
||||
<Delete Files="@(OldCLZFiles)" Condition="@(OldCLZFiles) != ''">
|
||||
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
|
||||
</Delete>
|
||||
<Message Text="Deleted files: '@(DeletedList)'" />
|
||||
<Message Text="Deleted old CLZ files: '@(DeletedList)'" Condition="@(DeletedList) != ''" />
|
||||
</Target>
|
||||
<Target Name="DeleteCPZ" BeforeTargets="PreBuildEvent" Condition="$(ProjectType) == 'Program' And $(TargetDir) != '' And Exists($(FileName))">
|
||||
<Delete Files="$(TargetDir)$(TargetName).$(Version).$(TargetFramework).cpz">
|
||||
<Target Name="DeleteCPZ" BeforeTargets="CoreBuild" Condition="$(ProjectType) == 'Program' And $(TargetDir) != ''">
|
||||
<ItemGroup>
|
||||
<OldCPZFiles Include="$(TargetDir)$(TargetName).*.$(TargetFramework).cpz" />
|
||||
</ItemGroup>
|
||||
<Delete Files="@(OldCPZFiles)" Condition="@(OldCPZFiles) != ''">
|
||||
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
|
||||
</Delete>
|
||||
<Message Text="Deleted files: '@(DeletedList)'" />
|
||||
<Message Text="Deleted old CPZ files: '@(DeletedList)'" Condition="@(DeletedList) != ''" />
|
||||
</Target>
|
||||
<Target Name="DeleteCPLZ" BeforeTargets="PreBuildEvent" Condition="$(ProjectType) == 'ProgramLibrary' And $(TargetDir) != '' And Exists($(FileName))">
|
||||
<Delete Files="$(TargetDir)$(TargetName).$(Version).$(TargetFramework).cplz">
|
||||
<Target Name="DeleteCPLZ" BeforeTargets="CoreBuild" Condition="$(ProjectType) == 'ProgramLibrary' And $(TargetDir) != ''">
|
||||
<ItemGroup>
|
||||
<OldCPLZFiles Include="$(TargetDir)$(TargetName).*.$(TargetFramework).cplz" />
|
||||
</ItemGroup>
|
||||
<Delete Files="@(OldCPLZFiles)" Condition="@(OldCPLZFiles) != ''">
|
||||
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
|
||||
</Delete>
|
||||
<Message Text="Deleted files: '@(DeletedList)'" />
|
||||
<Message Text="Deleted old CPLZ files: '@(DeletedList)'" Condition="@(DeletedList) != ''" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CreateCPLZ" AfterTargets="Build" Condition="$(ProjectType) == 'ProgramLibrary' And $(TargetDir) != ''" DependsOnTargets="DeleteCPLZ">
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -9,40 +9,59 @@ using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Core.Config
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads a Portal formatted config file
|
||||
/// </summary>
|
||||
public class PortalConfigReader
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads the config file, checks if it needs a merge, merges and saves, then returns the merged Object.
|
||||
/// </summary>
|
||||
/// <returns>JObject of config file</returns>
|
||||
public static void ReadAndMergeFileIfNecessary(string filePath, string savePath)
|
||||
const string template = "template";
|
||||
const string system = "system";
|
||||
const string systemUrl = "system_url";
|
||||
const string templateUrl = "template_url";
|
||||
const string info = "info";
|
||||
const string devices = "devices";
|
||||
const string rooms = "rooms";
|
||||
const string sourceLists = "sourceLists";
|
||||
const string destinationLists = "destinationLists";
|
||||
const string cameraLists = "cameraLists";
|
||||
const string audioControlPointLists = "audioControlPointLists";
|
||||
|
||||
const string tieLines = "tieLines";
|
||||
const string joinMaps = "joinMaps";
|
||||
const string global = "global";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads the config file, checks if it needs a merge, merges and saves, then returns the merged Object.
|
||||
/// </summary>
|
||||
/// <returns>JObject of config file</returns>
|
||||
public static void ReadAndMergeFileIfNecessary(string filePath, string savePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Error,
|
||||
Debug.LogError(
|
||||
"ERROR: Configuration file not present. Please load file to {0} and reset program", filePath);
|
||||
}
|
||||
|
||||
using (StreamReader fs = new StreamReader(filePath))
|
||||
{
|
||||
var jsonObj = JObject.Parse(fs.ReadToEnd());
|
||||
if(jsonObj["template"] != null && jsonObj["system"] != null)
|
||||
if(jsonObj[template] != null && jsonObj[system] != null)
|
||||
{
|
||||
// it's a double-config, merge it.
|
||||
var merged = MergeConfigs(jsonObj);
|
||||
if (jsonObj["system_url"] != null)
|
||||
if (jsonObj[systemUrl] != null)
|
||||
{
|
||||
merged["systemUrl"] = jsonObj["system_url"].Value<string>();
|
||||
merged[systemUrl] = jsonObj[systemUrl].Value<string>();
|
||||
}
|
||||
|
||||
if (jsonObj["template_url"] != null)
|
||||
if (jsonObj[templateUrl] != null)
|
||||
{
|
||||
merged["templateUrl"] = jsonObj["template_url"].Value<string>();
|
||||
merged[templateUrl] = jsonObj[templateUrl].Value<string>();
|
||||
}
|
||||
|
||||
jsonObj = merged;
|
||||
@@ -77,62 +96,62 @@ namespace PepperDash.Core.Config
|
||||
var merged = new JObject();
|
||||
|
||||
// Put together top-level objects
|
||||
if (system["info"] != null)
|
||||
merged.Add("info", Merge(template["info"], system["info"], "infO"));
|
||||
if (system[info] != null)
|
||||
merged.Add(info, Merge(template[info], system[info], info));
|
||||
else
|
||||
merged.Add("info", template["info"]);
|
||||
merged.Add(info, template[info]);
|
||||
|
||||
merged.Add("devices", MergeArraysOnTopLevelProperty(template["devices"] as JArray,
|
||||
system["devices"] as JArray, "key", "devices"));
|
||||
merged.Add(devices, MergeArraysOnTopLevelProperty(template[devices] as JArray,
|
||||
system[devices] as JArray, "key", devices));
|
||||
|
||||
if (system["rooms"] == null)
|
||||
merged.Add("rooms", template["rooms"]);
|
||||
if (system[rooms] == null)
|
||||
merged.Add(rooms, template[rooms]);
|
||||
else
|
||||
merged.Add("rooms", MergeArraysOnTopLevelProperty(template["rooms"] as JArray,
|
||||
system["rooms"] as JArray, "key", "rooms"));
|
||||
merged.Add(rooms, MergeArraysOnTopLevelProperty(template[rooms] as JArray,
|
||||
system[rooms] as JArray, "key", rooms));
|
||||
|
||||
if (system["sourceLists"] == null)
|
||||
merged.Add("sourceLists", template["sourceLists"]);
|
||||
if (system[sourceLists] == null)
|
||||
merged.Add(sourceLists, template[sourceLists]);
|
||||
else
|
||||
merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"], "sourceLists"));
|
||||
merged.Add(sourceLists, Merge(template[sourceLists], system[sourceLists], sourceLists));
|
||||
|
||||
if (system["destinationLists"] == null)
|
||||
merged.Add("destinationLists", template["destinationLists"]);
|
||||
if (system[destinationLists] == null)
|
||||
merged.Add(destinationLists, template[destinationLists]);
|
||||
else
|
||||
merged.Add("destinationLists",
|
||||
Merge(template["destinationLists"], system["destinationLists"], "destinationLists"));
|
||||
merged.Add(destinationLists,
|
||||
Merge(template[destinationLists], system[destinationLists], destinationLists));
|
||||
|
||||
|
||||
if (system["cameraLists"] == null)
|
||||
merged.Add("cameraLists", template["cameraLists"]);
|
||||
if (system[cameraLists] == null)
|
||||
merged.Add(cameraLists, template[cameraLists]);
|
||||
else
|
||||
merged.Add("cameraLists", Merge(template["cameraLists"], system["cameraLists"], "cameraLists"));
|
||||
merged.Add(cameraLists, Merge(template[cameraLists], system[cameraLists], cameraLists));
|
||||
|
||||
if (system["audioControlPointLists"] == null)
|
||||
merged.Add("audioControlPointLists", template["audioControlPointLists"]);
|
||||
if (system[audioControlPointLists] == null)
|
||||
merged.Add(audioControlPointLists, template[audioControlPointLists]);
|
||||
else
|
||||
merged.Add("audioControlPointLists",
|
||||
Merge(template["audioControlPointLists"], system["audioControlPointLists"], "audioControlPointLists"));
|
||||
merged.Add(audioControlPointLists,
|
||||
Merge(template[audioControlPointLists], system[audioControlPointLists], audioControlPointLists));
|
||||
|
||||
|
||||
// Template tie lines take precedence. Config tool doesn't do them at system
|
||||
// level anyway...
|
||||
if (template["tieLines"] != null)
|
||||
merged.Add("tieLines", template["tieLines"]);
|
||||
else if (system["tieLines"] != null)
|
||||
merged.Add("tieLines", system["tieLines"]);
|
||||
if (template[tieLines] != null)
|
||||
merged.Add(tieLines, template[tieLines]);
|
||||
else if (system[tieLines] != null)
|
||||
merged.Add(tieLines, system[tieLines]);
|
||||
else
|
||||
merged.Add("tieLines", new JArray());
|
||||
merged.Add(tieLines, new JArray());
|
||||
|
||||
if (template["joinMaps"] != null)
|
||||
merged.Add("joinMaps", template["joinMaps"]);
|
||||
if (template[joinMaps] != null)
|
||||
merged.Add(joinMaps, template[joinMaps]);
|
||||
else
|
||||
merged.Add("joinMaps", new JObject());
|
||||
merged.Add(joinMaps, new JObject());
|
||||
|
||||
if (system["global"] != null)
|
||||
merged.Add("global", Merge(template["global"], system["global"], "global"));
|
||||
if (system[global] != null)
|
||||
merged.Add(global, Merge(template[global], system[global], global));
|
||||
else
|
||||
merged.Add("global", template["global"]);
|
||||
merged.Add(global, template[global]);
|
||||
|
||||
//Debug.Console(2, "MERGED CONFIG RESULT: \x0d\x0a{0}", merged);
|
||||
return merged;
|
||||
@@ -228,7 +247,7 @@ namespace PepperDash.Core.Config
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Warning, "Cannot merge items at path {0}: \r{1}", propPath, e);
|
||||
Debug.LogError($"Cannot merge items at path {propPath}: \r{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using System.Reflection;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
@@ -355,22 +353,22 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// </summary>
|
||||
public class EiscApiPropertiesConfig
|
||||
{
|
||||
[JsonProperty("control")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Control
|
||||
/// </summary>
|
||||
[JsonProperty("control")]
|
||||
public EssentialsControlPropertiesConfig Control { get; set; }
|
||||
|
||||
[JsonProperty("devices")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Devices
|
||||
/// </summary>
|
||||
[JsonProperty("devices")]
|
||||
public List<ApiDevicePropertiesConfig> Devices { get; set; }
|
||||
|
||||
[JsonProperty("rooms")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Rooms
|
||||
/// </summary>
|
||||
[JsonProperty("rooms")]
|
||||
public List<ApiRoomPropertiesConfig> Rooms { get; set; }
|
||||
|
||||
|
||||
@@ -379,22 +377,22 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// </summary>
|
||||
public class ApiDevicePropertiesConfig
|
||||
{
|
||||
[JsonProperty("deviceKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the DeviceKey
|
||||
/// </summary>
|
||||
[JsonProperty("deviceKey")]
|
||||
public string DeviceKey { get; set; }
|
||||
|
||||
[JsonProperty("joinStart")]
|
||||
/// <summary>
|
||||
/// Gets or sets the JoinStart
|
||||
/// </summary>
|
||||
[JsonProperty("joinStart")]
|
||||
public uint JoinStart { get; set; }
|
||||
|
||||
[JsonProperty("joinMapKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the JoinMapKey
|
||||
/// </summary>
|
||||
[JsonProperty("joinMapKey")]
|
||||
public string JoinMapKey { get; set; }
|
||||
}
|
||||
|
||||
@@ -403,22 +401,22 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// </summary>
|
||||
public class ApiRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("roomKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the RoomKey
|
||||
/// </summary>
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
[JsonProperty("joinStart")]
|
||||
/// <summary>
|
||||
/// Gets or sets the JoinStart
|
||||
/// </summary>
|
||||
[JsonProperty("joinStart")]
|
||||
public uint JoinStart { get; set; }
|
||||
|
||||
[JsonProperty("joinMapKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the JoinMapKey
|
||||
/// </summary>
|
||||
[JsonProperty("joinMapKey")]
|
||||
public string JoinMapKey { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -18,41 +18,41 @@ namespace PepperDash.Essentials.Core.Config
|
||||
/// </summary>
|
||||
public class DeviceConfig
|
||||
{
|
||||
[JsonProperty("key")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Key
|
||||
/// </summary>
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("uid")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Uid
|
||||
/// </summary>
|
||||
[JsonProperty("uid")]
|
||||
public int Uid { get; set; }
|
||||
|
||||
[JsonProperty("name")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Name
|
||||
/// </summary>
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("group")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Group
|
||||
/// </summary>
|
||||
[JsonProperty("group")]
|
||||
public string Group { get; set; }
|
||||
|
||||
[JsonProperty("type")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Type
|
||||
/// </summary>
|
||||
[JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[JsonProperty("properties")]
|
||||
[JsonConverter(typeof(DevicePropertiesConverter))]
|
||||
/// <summary>
|
||||
/// Gets or sets the Properties
|
||||
/// </summary>
|
||||
[JsonProperty("properties")]
|
||||
[JsonConverter(typeof(DevicePropertiesConverter))]
|
||||
public JToken Properties { get; set; }
|
||||
|
||||
public DeviceConfig(DeviceConfig dc)
|
||||
@@ -68,7 +68,7 @@ namespace PepperDash.Essentials.Core.Config
|
||||
//Properties = JToken.FromObject(dc.Properties);
|
||||
}
|
||||
|
||||
public DeviceConfig() {}
|
||||
public DeviceConfig() { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -124,22 +124,35 @@ namespace PepperDash.Essentials.Core.Config
|
||||
Debug.LogMessage(LogEventLevel.Information, "Successfully Loaded Local Config");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var doubleObj = JObject.Parse(fs.ReadToEnd());
|
||||
ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
|
||||
var parsedConfig = JObject.Parse(fs.ReadToEnd());
|
||||
|
||||
// Extract SystemUrl and TemplateUrl into final config output
|
||||
|
||||
if (doubleObj["system_url"] != null)
|
||||
// Check if it's a v2 config (check for "version" node)
|
||||
// this means it's already merged by the Portal API
|
||||
// from the v2 config tool
|
||||
var isV2Config = parsedConfig["versions"] != null;
|
||||
|
||||
if (isV2Config)
|
||||
{
|
||||
ConfigObject.SystemUrl = doubleObj["system_url"].Value<string>();
|
||||
Debug.LogMessage(LogEventLevel.Information, "Config file is a v2 format, no merge necessary.");
|
||||
ConfigObject = parsedConfig.ToObject<EssentialsConfig>();
|
||||
Debug.LogMessage(LogEventLevel.Information, "Successfully Loaded v2 Config");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (doubleObj["template_url"] != null)
|
||||
// Extract SystemUrl and TemplateUrl into final config output
|
||||
ConfigObject = PortalConfigReader.MergeConfigs(parsedConfig).ToObject<EssentialsConfig>();
|
||||
|
||||
if (parsedConfig["system_url"] != null)
|
||||
{
|
||||
ConfigObject.TemplateUrl = doubleObj["template_url"].Value<string>();
|
||||
ConfigObject.SystemUrl = parsedConfig["system_url"].Value<string>();
|
||||
}
|
||||
|
||||
if (parsedConfig["template_url"] != null)
|
||||
{
|
||||
ConfigObject.TemplateUrl = parsedConfig["template_url"].Value<string>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,21 @@ namespace PepperDash.Essentials.Core.Config
|
||||
/// </summary>
|
||||
public class EssentialsConfig : BasicConfig
|
||||
{
|
||||
[JsonProperty("system_url")]
|
||||
/// <summary>
|
||||
/// Gets or sets the SystemUrl
|
||||
/// </summary>
|
||||
[JsonProperty("system_url")]
|
||||
public string SystemUrl { get; set; }
|
||||
|
||||
[JsonProperty("template_url")]
|
||||
/// <summary>
|
||||
/// Gets or sets the TemplateUrl
|
||||
/// </summary>
|
||||
[JsonProperty("template_url")]
|
||||
public string TemplateUrl { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SystemUuid extracted from the SystemUrl
|
||||
/// </summary>
|
||||
[JsonProperty("systemUuid")]
|
||||
public string SystemUuid
|
||||
{
|
||||
@@ -45,6 +53,9 @@ namespace PepperDash.Essentials.Core.Config
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the TemplateUuid extracted from the TemplateUrl
|
||||
/// </summary>
|
||||
[JsonProperty("templateUuid")]
|
||||
public string TemplateUuid
|
||||
{
|
||||
@@ -67,30 +78,84 @@ namespace PepperDash.Essentials.Core.Config
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("rooms")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Rooms
|
||||
/// </summary>
|
||||
[JsonProperty("rooms")]
|
||||
public List<DeviceConfig> Rooms { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Versions
|
||||
/// </summary>
|
||||
public VersionData Versions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EssentialsConfig"/> class.
|
||||
/// </summary>
|
||||
public EssentialsConfig()
|
||||
: base()
|
||||
{
|
||||
Rooms = new List<DeviceConfig>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a SystemTemplateConfigs
|
||||
/// </summary>
|
||||
public class SystemTemplateConfigs
|
||||
|
||||
/// <summary>
|
||||
/// Represents version data for Essentials and its packages
|
||||
/// </summary>
|
||||
public class VersionData
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Essentials version
|
||||
/// </summary>
|
||||
[JsonProperty("essentials")]
|
||||
public NugetVersion Essentials { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of Packages
|
||||
/// </summary>
|
||||
[JsonProperty("packages")]
|
||||
public List<NugetVersion> Packages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="VersionData"/> class.
|
||||
/// </summary>
|
||||
public VersionData()
|
||||
{
|
||||
Packages = new List<NugetVersion>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a NugetVersion
|
||||
/// </summary>
|
||||
public class NugetVersion
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Version
|
||||
/// </summary>
|
||||
[JsonProperty("version")]
|
||||
public string Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the PackageId
|
||||
/// </summary>
|
||||
[JsonProperty("packageId")]
|
||||
public string PackageId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a SystemTemplateConfigs
|
||||
/// </summary>
|
||||
public class SystemTemplateConfigs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the System
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the System
|
||||
/// </summary>
|
||||
public EssentialsConfig System { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Template
|
||||
/// </summary>
|
||||
public EssentialsConfig Template { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,59 +2,54 @@
|
||||
|
||||
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;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
[Description("Wrapper class for Digital Input")]
|
||||
|
||||
/// <summary>
|
||||
/// Represents a GenericDigitalInputDevice
|
||||
/// </summary>
|
||||
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
|
||||
/// [Description("Wrapper class for Digital Input")]
|
||||
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IHasFeedback
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the InputPort
|
||||
/// </summary>
|
||||
public DigitalInput InputPort { get; private set; }
|
||||
private DigitalInput inputPort;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the InputStateFeedback
|
||||
/// </summary>
|
||||
public BoolFeedback InputStateFeedback { get; private set; }
|
||||
|
||||
Func<bool> InputStateFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => InputPort.State;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GenericDigitalInputDevice"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">key for device</param>
|
||||
/// <param name="name">name for device</param>
|
||||
/// <param name="postActivationFunc">function to call after activation. Should return the DigitalInput</param>
|
||||
/// <param name="config">config for device</param>
|
||||
public GenericDigitalInputDevice(string key, string name, Func<IOPortConfig, DigitalInput> postActivationFunc,
|
||||
IOPortConfig config)
|
||||
: base(key, name)
|
||||
{
|
||||
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
|
||||
InputStateFeedback = new BoolFeedback("inputState", () => inputPort.State);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
InputPort = postActivationFunc(config);
|
||||
inputPort = postActivationFunc(config);
|
||||
|
||||
InputPort.Register();
|
||||
|
||||
InputPort.StateChange += InputPort_StateChange;
|
||||
inputPort.Register();
|
||||
|
||||
inputPort.StateChange += InputPort_StateChange;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -71,41 +66,31 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
private static DigitalInput GetDigitalInput(IOPortConfig dc)
|
||||
{
|
||||
IDigitalInputPorts ioPortDevice;
|
||||
|
||||
if (dc.PortDeviceKey.Equals("processor"))
|
||||
{
|
||||
if (!Global.ControlSystem.SupportsDigitalInput)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Processor does not support Digital Inputs");
|
||||
Debug.LogError("GetDigitalInput: Processor does not support Digital Inputs");
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = Global.ControlSystem;
|
||||
|
||||
return Global.ControlSystem.DigitalInputPorts[dc.PortNumber];
|
||||
}
|
||||
else
|
||||
|
||||
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IDigitalInputPorts ioPortDevice))
|
||||
{
|
||||
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IDigitalInputPorts;
|
||||
if (ioPortDev == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = ioPortDev;
|
||||
}
|
||||
if (ioPortDevice == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device '0' is not a valid IDigitalInputPorts Device", dc.PortDeviceKey);
|
||||
Debug.LogError("GetDigitalInput: Device {key} is not a valid device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (dc.PortNumber > ioPortDevice.NumberOfDigitalInputPorts)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
|
||||
Debug.LogError("GetDigitalInput: Device {key} does not contain a digital input port {port}", dc.PortDeviceKey, dc.PortNumber);
|
||||
return null;
|
||||
}
|
||||
|
||||
return ioPortDevice.DigitalInputPorts[dc.PortNumber];
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -131,20 +116,20 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
// Link feedback for input state
|
||||
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
|
||||
this.LogError("Unable to link device {key}. {message}", Key, e.Message);
|
||||
this.LogDebug(e, "Stack Trace: ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,22 +138,22 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
#region Factory
|
||||
|
||||
/// <summary>
|
||||
/// Represents a GenericDigitalInputDeviceFactory
|
||||
/// Factory for creating GenericDigitalInputDevice devices
|
||||
/// </summary>
|
||||
public class GenericDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericDigitalInputDevice>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for GenericDigitalInputDeviceFactory
|
||||
/// </summary>
|
||||
public GenericDigitalInputDeviceFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "digitalinput" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Digital Input Device");
|
||||
Debug.LogDebug("Factory Attempting to create new Generic Digital Input Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());
|
||||
|
||||
|
||||
@@ -2,66 +2,64 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Serilog.Events;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic digital input deviced tied to a versiport
|
||||
/// </summary>
|
||||
public class GenericVersiportAnalogInputDevice : EssentialsBridgeableDevice, IAnalogInput
|
||||
public class GenericVersiportAnalogInputDevice : EssentialsBridgeableDevice, IAnalogInput, IHasFeedback
|
||||
{
|
||||
public Versiport InputPort { get; private set; }
|
||||
private Versiport inputPort;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IntFeedback InputValueFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the InputMinimumChangeFeedback
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Updates when the analog input minimum change value changes
|
||||
/// </remarks>
|
||||
public IntFeedback InputMinimumChangeFeedback { get; private set; }
|
||||
|
||||
Func<int> InputValueFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => InputPort.AnalogIn;
|
||||
}
|
||||
}
|
||||
|
||||
Func<int> InputMinimumChangeFeedbackFunc
|
||||
{
|
||||
get { return () => InputPort.AnalogMinChange; }
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GenericVersiportAnalogInputDevice"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">key for the device</param>
|
||||
/// <param name="name">name for the device</param>
|
||||
/// <param name="postActivationFunc">function to call after activation</param>
|
||||
/// <param name="config">IO port configuration</param>
|
||||
public GenericVersiportAnalogInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
|
||||
base(key, name)
|
||||
{
|
||||
InputValueFeedback = new IntFeedback(InputValueFeedbackFunc);
|
||||
InputMinimumChangeFeedback = new IntFeedback(InputMinimumChangeFeedbackFunc);
|
||||
InputValueFeedback = new IntFeedback("inputValue", () => inputPort.AnalogIn);
|
||||
InputMinimumChangeFeedback = new IntFeedback("inputMinimumChange", () => inputPort.AnalogMinChange);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
InputPort = postActivationFunc(config);
|
||||
inputPort = postActivationFunc(config);
|
||||
|
||||
InputPort.Register();
|
||||
inputPort.Register();
|
||||
|
||||
InputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput);
|
||||
InputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655);
|
||||
inputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput);
|
||||
inputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655);
|
||||
if (config.DisablePullUpResistor)
|
||||
InputPort.DisablePullUpResistor = true;
|
||||
inputPort.DisablePullUpResistor = true;
|
||||
|
||||
InputPort.VersiportChange += InputPort_VersiportChange;
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportAnalogInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
|
||||
inputPort.VersiportChange += InputPort_VersiportChange;
|
||||
|
||||
this.LogDebug("Created GenericVersiportAnalogInputDevice on port {port}. DisablePullUpResistor: {pullUpResistorDisabled}", config.PortNumber, inputPort.DisablePullUpResistor);
|
||||
});
|
||||
|
||||
}
|
||||
@@ -69,20 +67,17 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
/// <summary>
|
||||
/// Set minimum voltage change for device to update voltage changed method
|
||||
/// </summary>
|
||||
/// <param name="value">valid values range from 0 - 65535, representing the full 100% range of the processor voltage source. Check processor documentation for details</param>
|
||||
/// <summary>
|
||||
/// SetMinimumChange method
|
||||
/// </summary>
|
||||
/// <param name="value">valid values range from 0 - 65535, representing the full 100% range of the processor voltage source. Check processor documentation for details</param>
|
||||
public void SetMinimumChange(ushort value)
|
||||
{
|
||||
InputPort.AnalogMinChange = value;
|
||||
inputPort.AnalogMinChange = value;
|
||||
}
|
||||
|
||||
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event);
|
||||
this.LogDebug("Versiport change: {event}", args.Event);
|
||||
|
||||
if(args.Event == eVersiportEvent.AnalogInChange)
|
||||
if (args.Event == eVersiportEvent.AnalogInChange)
|
||||
InputValueFeedback.FireUpdate();
|
||||
if (args.Event == eVersiportEvent.AnalogMinChangeChange)
|
||||
InputMinimumChangeFeedback.FireUpdate();
|
||||
@@ -91,9 +86,6 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
#region Bridge Linking
|
||||
|
||||
/// <summary>
|
||||
/// LinkToApi method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
@@ -110,12 +102,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
this.LogDebug("Linking to Trilist '{trilistId}'", trilist.ID.ToString("X"));
|
||||
|
||||
// Link feedback for input state
|
||||
InputValueFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputValue.JoinNumber]);
|
||||
@@ -125,8 +117,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
|
||||
this.LogError("Unable to link device {key}: {message}", Key, e.Message);
|
||||
this.LogDebug(e, "Stack Trace: ");
|
||||
}
|
||||
|
||||
trilist.OnlineStatusChange += (d, args) =>
|
||||
@@ -138,11 +130,6 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
}
|
||||
|
||||
void trilist_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -151,70 +138,55 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
/// </summary>
|
||||
public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
|
||||
{
|
||||
|
||||
IIOPorts ioPortDevice;
|
||||
|
||||
if (dc.PortDeviceKey.Equals("processor"))
|
||||
{
|
||||
if (!Global.ControlSystem.SupportsVersiport)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Processor does not support Versiports");
|
||||
Debug.LogError("GetVersiportAnalogInput: Processor does not support Versiports");
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = Global.ControlSystem;
|
||||
return Global.ControlSystem.VersiPorts[dc.PortNumber];
|
||||
}
|
||||
else
|
||||
|
||||
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
|
||||
{
|
||||
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
|
||||
if (ioPortDev == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} is not a valid device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = ioPortDev;
|
||||
}
|
||||
if (ioPortDevice == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
|
||||
Debug.LogError("GetVersiportAnalogInput: Device {key} is not a valid device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
|
||||
Debug.LogError("GetVersiportAnalogInput: Device {key} does not contain a port {port}", dc.PortDeviceKey, dc.PortNumber);
|
||||
return null;
|
||||
}
|
||||
if(!ioPortDevice.VersiPorts[dc.PortNumber].SupportsAnalogInput)
|
||||
if (!ioPortDevice.VersiPorts[dc.PortNumber].SupportsAnalogInput)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} does not support AnalogInput on port {1}", dc.PortDeviceKey, dc.PortNumber);
|
||||
Debug.LogError("GetVersiportAnalogInput: Device {key} does not support AnalogInput on port {port}", dc.PortDeviceKey, dc.PortNumber);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return ioPortDevice.VersiPorts[dc.PortNumber];
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a GenericVersiportAbalogInputDeviceFactory
|
||||
/// Factory for creating GenericVersiportAnalogInputDevice devices
|
||||
/// </summary>
|
||||
public class GenericVersiportAbalogInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportAnalogInputDevice>
|
||||
public class GenericVersiportAnalogInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportAnalogInputDevice>
|
||||
{
|
||||
public GenericVersiportAbalogInputDeviceFactory()
|
||||
/// <summary>
|
||||
/// Constructor for GenericVersiportAnalogInputDeviceFactory
|
||||
/// </summary>
|
||||
public GenericVersiportAnalogInputDeviceFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "versiportanaloginput" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device");
|
||||
Debug.LogDebug("Factory Attempting to create new Generic Versiport Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());
|
||||
|
||||
|
||||
@@ -2,78 +2,82 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Serilog.Events;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic digital input deviced tied to a versiport
|
||||
/// </summary>
|
||||
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider
|
||||
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider, IHasFeedback
|
||||
{
|
||||
public Versiport InputPort { get; private set; }
|
||||
private Versiport inputPort;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the InputStateFeedback
|
||||
/// </summary>
|
||||
public BoolFeedback InputStateFeedback { get; private set; }
|
||||
|
||||
Func<bool> InputStateFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => InputPort.DigitalIn;
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the PartitionPresentFeedback
|
||||
/// </summary>
|
||||
public BoolFeedback PartitionPresentFeedback { get; }
|
||||
|
||||
public bool PartitionPresent => !InputStateFeedbackFunc();
|
||||
/// <summary>
|
||||
/// Get partition state
|
||||
/// </summary>
|
||||
public bool PartitionPresent => !inputPort.DigitalIn;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GenericVersiportDigitalInputDevice"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">key for device</param>
|
||||
/// <param name="name">name for device</param>
|
||||
/// <param name="postActivationFunc">function to call after activation. Should return the Versiport</param>
|
||||
/// <param name="config">config for device</param>
|
||||
public GenericVersiportDigitalInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
|
||||
base(key, name)
|
||||
{
|
||||
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
|
||||
PartitionPresentFeedback = new BoolFeedback(() => !InputStateFeedbackFunc());
|
||||
InputStateFeedback = new BoolFeedback("inputState", () => inputPort.DigitalIn);
|
||||
PartitionPresentFeedback = new BoolFeedback("partitionPresent", () => !inputPort.DigitalIn);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
InputPort = postActivationFunc(config);
|
||||
inputPort = postActivationFunc(config);
|
||||
|
||||
InputPort.Register();
|
||||
inputPort.Register();
|
||||
|
||||
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
|
||||
inputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
|
||||
if (config.DisablePullUpResistor)
|
||||
InputPort.DisablePullUpResistor = true;
|
||||
inputPort.DisablePullUpResistor = true;
|
||||
|
||||
InputPort.VersiportChange += InputPort_VersiportChange;
|
||||
inputPort.VersiportChange += InputPort_VersiportChange;
|
||||
|
||||
InputStateFeedback.FireUpdate();
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
|
||||
this.LogDebug("Created GenericVersiportDigitalInputDevice for port {port}. DisablePullUpResistor: {pullUpResistorDisable}", config.PortNumber, inputPort.DisablePullUpResistor);
|
||||
|
||||
});
|
||||
|
||||
Feedbacks.Add(InputStateFeedback);
|
||||
Feedbacks.Add(PartitionPresentFeedback);
|
||||
}
|
||||
|
||||
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event);
|
||||
this.LogDebug("Versiport change: {0}", args.Event);
|
||||
|
||||
if(args.Event == eVersiportEvent.DigitalInChange)
|
||||
if (args.Event == eVersiportEvent.DigitalInChange)
|
||||
{
|
||||
InputStateFeedback.FireUpdate();
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
@@ -102,20 +106,20 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
// Link feedback for input state
|
||||
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
|
||||
this.LogError("Unable to link device {key}. Input is null. {message}", Key, e.Message);
|
||||
this.LogDebug(e, "Stack Trace: ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,63 +131,50 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
/// </summary>
|
||||
public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
|
||||
{
|
||||
|
||||
IIOPorts ioPortDevice;
|
||||
|
||||
if (dc.PortDeviceKey.Equals("processor"))
|
||||
{
|
||||
if (!Global.ControlSystem.SupportsVersiport)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Processor does not support Versiports");
|
||||
Debug.LogError("GetVersiportDigitalInput: Processor does not support Versiports");
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = Global.ControlSystem;
|
||||
return Global.ControlSystem.VersiPorts[dc.PortNumber];
|
||||
}
|
||||
else
|
||||
|
||||
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
|
||||
{
|
||||
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
|
||||
if (ioPortDev == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = ioPortDev;
|
||||
}
|
||||
if (ioPortDevice == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
|
||||
Debug.LogError("GetVersiportDigitalInput: Device {key} is not a valid device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
|
||||
Debug.LogError("GetVersiportDigitalInput: Device {key} does not contain versiport {port}", dc.PortDeviceKey, dc.PortNumber);
|
||||
return null;
|
||||
}
|
||||
|
||||
return ioPortDevice.VersiPorts[dc.PortNumber];
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a GenericVersiportDigitalInputDeviceFactory
|
||||
/// Factory class for GenericVersiportDigitalInputDevice
|
||||
/// </summary>
|
||||
public class GenericVersiportDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for GenericVersiportDigitalInputDeviceFactory
|
||||
/// </summary>
|
||||
public GenericVersiportDigitalInputDeviceFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "versiportinput" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device");
|
||||
Debug.LogDebug("Factory Attempting to create new Generic Versiport Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());
|
||||
|
||||
|
||||
@@ -2,18 +2,13 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
@@ -21,76 +16,68 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
/// <summary>
|
||||
/// Represents a generic digital input deviced tied to a versiport
|
||||
/// </summary>
|
||||
public class GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput
|
||||
public class GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput, IHasFeedback
|
||||
{
|
||||
public Versiport OutputPort { get; private set; }
|
||||
private Versiport outputPort;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputStateFeedback
|
||||
/// </summary>
|
||||
public BoolFeedback OutputStateFeedback { get; private set; }
|
||||
|
||||
Func<bool> OutputStateFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => OutputPort.DigitalOut;
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GenericVersiportDigitalOutputDevice"/> class.
|
||||
/// </summary>
|
||||
public GenericVersiportDigitalOutputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
|
||||
base(key, name)
|
||||
{
|
||||
OutputStateFeedback = new BoolFeedback(OutputStateFeedbackFunc);
|
||||
OutputStateFeedback = new BoolFeedback("outputState", () => outputPort.DigitalOut);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
OutputPort = postActivationFunc(config);
|
||||
outputPort = postActivationFunc(config);
|
||||
|
||||
OutputPort.Register();
|
||||
outputPort.Register();
|
||||
|
||||
|
||||
if (!OutputPort.SupportsDigitalOutput)
|
||||
if (!outputPort.SupportsDigitalOutput)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Device does not support configuration as a Digital Output");
|
||||
this.LogError("Device does not support configuration as a Digital Output");
|
||||
return;
|
||||
}
|
||||
|
||||
OutputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput);
|
||||
outputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput);
|
||||
|
||||
|
||||
OutputPort.VersiportChange += OutputPort_VersiportChange;
|
||||
outputPort.VersiportChange += OutputPort_VersiportChange;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void OutputPort_VersiportChange(Versiport port, VersiportEventArgs args)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event);
|
||||
this.LogDebug("Versiport change: {event}", args.Event);
|
||||
|
||||
if(args.Event == eVersiportEvent.DigitalOutChange)
|
||||
if (args.Event == eVersiportEvent.DigitalOutChange)
|
||||
OutputStateFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set value of the versiport digital output
|
||||
/// </summary>
|
||||
/// <param name="state">value to set the output to</param>
|
||||
/// <summary>
|
||||
/// SetOutput method
|
||||
/// </summary>
|
||||
/// <param name="state">value to set the output to</param>
|
||||
public void SetOutput(bool state)
|
||||
{
|
||||
if (OutputPort.SupportsDigitalOutput)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Passed the Check");
|
||||
|
||||
OutputPort.DigitalOut = state;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Versiport does not support Digital Output Mode");
|
||||
}
|
||||
if (!outputPort.SupportsDigitalOutput)
|
||||
{
|
||||
this.LogError("Versiport does not support Digital Output Mode");
|
||||
return;
|
||||
}
|
||||
|
||||
outputPort.DigitalOut = state;
|
||||
}
|
||||
|
||||
#region Bridge Linking
|
||||
@@ -114,12 +101,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
// Link feedback for input state
|
||||
OutputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OutputState.JoinNumber]);
|
||||
@@ -127,8 +114,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
|
||||
this.LogError("Unable to link device: {message}", e.Message);
|
||||
this.LogDebug(e, "Stack Trace: ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,41 +127,28 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
/// </summary>
|
||||
public static Versiport GetVersiportDigitalOutput(IOPortConfig dc)
|
||||
{
|
||||
|
||||
IIOPorts ioPortDevice;
|
||||
|
||||
if (dc.PortDeviceKey.Equals("processor"))
|
||||
if (dc.PortDeviceKey.Equals("processor"))
|
||||
{
|
||||
if (!Global.ControlSystem.SupportsVersiport)
|
||||
{
|
||||
if (!Global.ControlSystem.SupportsVersiport)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Processor does not support Versiports");
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = Global.ControlSystem;
|
||||
}
|
||||
else
|
||||
{
|
||||
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
|
||||
if (ioPortDev == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device {0} is not a valid device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = ioPortDev;
|
||||
}
|
||||
if (ioPortDevice == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device '0' is not a valid IOPorts Device", dc.PortDeviceKey);
|
||||
Debug.LogError("GetVersiportDigitalOutput: Processor does not support Versiports");
|
||||
return null;
|
||||
}
|
||||
return Global.ControlSystem.VersiPorts[dc.PortNumber];
|
||||
}
|
||||
|
||||
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
|
||||
}
|
||||
var port = ioPortDevice.VersiPorts[dc.PortNumber];
|
||||
return port;
|
||||
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
|
||||
{
|
||||
Debug.LogError("GetVersiportDigitalOutput: Device {key} is not a valid device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOutput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
|
||||
return null;
|
||||
}
|
||||
return ioPortDevice.VersiPorts[dc.PortNumber];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,18 +158,18 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
/// </summary>
|
||||
public class GenericVersiportDigitalOutputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="GenericVersiportDigitalOutputDeviceFactory"/> class.
|
||||
/// </summary>
|
||||
public GenericVersiportDigitalOutputDeviceFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "versiportoutput" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BuildDevice method
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device");
|
||||
Debug.LogDebug("Factory Attempting to create new Generic Versiport Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());
|
||||
|
||||
|
||||
@@ -12,6 +12,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
/// </summary>
|
||||
public interface IAnalogInput
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the InputValueFeedback.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Updates when the analog input value changes
|
||||
/// </remarks>
|
||||
IntFeedback InputValueFeedback { get; }
|
||||
}
|
||||
}
|
||||
@@ -14,25 +14,28 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
/// </summary>
|
||||
public class IOPortConfig
|
||||
{
|
||||
[JsonProperty("portDeviceKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the PortDeviceKey
|
||||
/// </summary>
|
||||
[JsonProperty("portDeviceKey")]
|
||||
public string PortDeviceKey { get; set; }
|
||||
[JsonProperty("portNumber")]
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the PortNumber
|
||||
/// </summary>
|
||||
[JsonProperty("portNumber")]
|
||||
public uint PortNumber { get; set; }
|
||||
[JsonProperty("disablePullUpResistor")]
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the DisablePullUpResistor
|
||||
/// </summary>
|
||||
[JsonProperty("disablePullUpResistor")]
|
||||
public bool DisablePullUpResistor { get; set; }
|
||||
[JsonProperty("minimumChange")]
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the MinimumChange
|
||||
/// </summary>
|
||||
[JsonProperty("minimumChange")]
|
||||
public int MinimumChange { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this interface on a device or room if it uses custom Mobile Control messengers
|
||||
/// </summary>
|
||||
public interface ICustomMobileControl : IKeyed
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,155 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this interface on a device or room if it uses custom Mobile Control messengers
|
||||
/// </summary>
|
||||
public interface ICustomMobileControl : IKeyed
|
||||
{
|
||||
}
|
||||
|
||||
/*/// <summary>
|
||||
/// Describes a MobileControlSystemController
|
||||
/// </summary>
|
||||
public interface IMobileControl : IKeyed
|
||||
{
|
||||
void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent);
|
||||
|
||||
void LinkSystemMonitorToAppServer();
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IMobileControl
|
||||
/// </summary>
|
||||
public interface IMobileControl : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the Host
|
||||
/// </summary>
|
||||
string Host { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Client App URL
|
||||
/// </summary>
|
||||
string ClientAppUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the System UUID
|
||||
/// </summary>
|
||||
string SystemUuid { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ApiOnlineAndAuthorized feedback
|
||||
/// </summary>
|
||||
BoolFeedback ApiOnlineAndAuthorized { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sends the message object to the AppServer
|
||||
/// </summary>
|
||||
/// <param name="o">Message to send</param>
|
||||
void SendMessageObject(IMobileControlMessage o);
|
||||
|
||||
/// <summary>
|
||||
/// Adds an action for a messenger
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Messenger type. Must implement IMobileControlMessenger</typeparam>
|
||||
/// <param name="messenger">messenger to register</param>
|
||||
/// <param name="action">action to add</param>
|
||||
void AddAction<T>(T messenger, Action<string, string, JToken> action) where T : IMobileControlMessenger;
|
||||
|
||||
/// <summary>
|
||||
/// Removes an action for a messenger
|
||||
/// </summary>
|
||||
/// <param name="key">key for action</param>
|
||||
void RemoveAction(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a device messenger
|
||||
/// </summary>
|
||||
/// <param name="messenger">Messenger to add</param>
|
||||
void AddDeviceMessenger(IMobileControlMessenger messenger);
|
||||
|
||||
/// <summary>
|
||||
/// Check if a device messenger exists
|
||||
/// </summary>
|
||||
/// <param name="key">Messenger key to find</param>
|
||||
bool CheckForDeviceMessenger(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Get a Room Messenger by key
|
||||
/// </summary>
|
||||
/// <param name="key">messenger key to find</param>
|
||||
/// <returns>Messenger if found, null otherwise</returns>
|
||||
IMobileControlRoomMessenger GetRoomMessenger(string key);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IMobileControlMessenger
|
||||
/// </summary>
|
||||
public interface IMobileControlMessenger : IKeyed
|
||||
{
|
||||
IMobileControl AppServerController { get; }
|
||||
string MessagePath { get; }
|
||||
|
||||
string DeviceKey { get; }
|
||||
void RegisterWithAppServer(IMobileControl appServerController);
|
||||
}
|
||||
|
||||
public interface IMobileControlMessage
|
||||
{
|
||||
[JsonProperty("type")]
|
||||
string Type { get; }
|
||||
|
||||
[JsonProperty("clientId", NullValueHandling = NullValueHandling.Ignore)]
|
||||
string ClientId { get; }
|
||||
|
||||
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
|
||||
JToken Content { get; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IMobileControlRoomMessenger
|
||||
/// </summary>
|
||||
public interface IMobileControlRoomMessenger : IKeyed
|
||||
{
|
||||
event EventHandler<EventArgs> UserCodeChanged;
|
||||
|
||||
event EventHandler<EventArgs> UserPromptedForCode;
|
||||
|
||||
event EventHandler<EventArgs> ClientJoined;
|
||||
|
||||
event EventHandler<EventArgs> AppUrlChanged;
|
||||
|
||||
string UserCode { get; }
|
||||
|
||||
string QrCodeUrl { get; }
|
||||
|
||||
string QrCodeChecksum { get; }
|
||||
|
||||
string McServerUrl { get; }
|
||||
|
||||
string RoomName { get; }
|
||||
|
||||
string AppUrl { get; }
|
||||
|
||||
void UpdateAppUrl(string url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IMobileControlAction
|
||||
/// </summary>
|
||||
public interface IMobileControlAction
|
||||
{
|
||||
IMobileControlMessenger Messenger { get; }
|
||||
|
||||
Action<string, string, JToken> Action { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the contract for IMobileControlTouchpanelController
|
||||
/// </summary>
|
||||
public interface IMobileControlTouchpanelController : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// The default room key for the controller
|
||||
/// </summary>
|
||||
string DefaultRoomKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the application URL for the controller
|
||||
/// </summary>
|
||||
/// <param name="url">The application URL</param>
|
||||
void SetAppUrl(string url);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the controller uses a direct server connection
|
||||
/// </summary>
|
||||
bool UseDirectServer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the controller is a Zoom Room controller
|
||||
/// </summary>
|
||||
bool ZoomRoomController { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a MobileControl Crestron Touchpanel Controller
|
||||
/// This interface extends the IMobileControlTouchpanelController to include connected IP information
|
||||
/// </summary>
|
||||
public interface IMobileControlCrestronTouchpanelController : IMobileControlTouchpanelController
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a collection of connected IP information for the touchpanel controller
|
||||
/// </summary>
|
||||
ReadOnlyCollection<ConnectedIpInformation> ConnectedIps { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IMobileControlAction
|
||||
/// </summary>
|
||||
public interface IMobileControlAction
|
||||
{
|
||||
IMobileControlMessenger Messenger { get; }
|
||||
|
||||
Action<string, string, JToken> Action { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes a MobileControl Crestron Touchpanel Controller
|
||||
/// This interface extends the IMobileControlTouchpanelController to include connected IP information
|
||||
/// </summary>
|
||||
public interface IMobileControlCrestronTouchpanelController : IMobileControlTouchpanelController
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a collection of connected IP information for the touchpanel controller
|
||||
/// </summary>
|
||||
ReadOnlyCollection<ConnectedIpInformation> ConnectedIps { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IMobileControlMessage
|
||||
{
|
||||
[JsonProperty("type")]
|
||||
string Type { get; }
|
||||
|
||||
[JsonProperty("clientId", NullValueHandling = NullValueHandling.Ignore)]
|
||||
string ClientId { get; }
|
||||
|
||||
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
|
||||
JToken Content { get; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IMobileControlMessenger
|
||||
/// </summary>
|
||||
public interface IMobileControlMessenger : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Parent controller for this messenger
|
||||
/// </summary>
|
||||
IMobileControl AppServerController { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Path to listen for messages
|
||||
/// </summary>
|
||||
string MessagePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Key of the device this messenger is associated with
|
||||
/// </summary>
|
||||
string DeviceKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Register this messenger with the AppServerController
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
void RegisterWithAppServer(IMobileControl appServerController);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IMobileControlMessenger
|
||||
/// </summary>
|
||||
public interface IMobileControlMessengerWithSubscriptions : IMobileControlMessenger
|
||||
{
|
||||
/// <summary>
|
||||
/// Unsubscribe a client from this messenger
|
||||
/// </summary>
|
||||
/// <param name="clientId"></param>
|
||||
void UnsubscribeClient(string clientId);
|
||||
|
||||
/// <summary>
|
||||
/// Register this messenger with the AppServerController
|
||||
/// </summary>
|
||||
/// <param name="appServerController">parent for this messenger</param>
|
||||
/// <param name="enableMessengerSubscriptions">Enable messenger subscriptions</param>
|
||||
void RegisterWithAppServer(IMobileControl appServerController, bool enableMessengerSubscriptions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IMobileControlRoomMessenger
|
||||
/// </summary>
|
||||
public interface IMobileControlRoomMessenger : IKeyed
|
||||
{
|
||||
event EventHandler<EventArgs> UserCodeChanged;
|
||||
|
||||
event EventHandler<EventArgs> UserPromptedForCode;
|
||||
|
||||
event EventHandler<EventArgs> ClientJoined;
|
||||
|
||||
event EventHandler<EventArgs> AppUrlChanged;
|
||||
|
||||
string UserCode { get; }
|
||||
|
||||
string QrCodeUrl { get; }
|
||||
|
||||
string QrCodeChecksum { get; }
|
||||
|
||||
string McServerUrl { get; }
|
||||
|
||||
string RoomName { get; }
|
||||
|
||||
string AppUrl { get; }
|
||||
|
||||
void UpdateAppUrl(string url);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IMobileControlTouchpanelController
|
||||
/// </summary>
|
||||
public interface IMobileControlTouchpanelController : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// The default room key for the controller
|
||||
/// </summary>
|
||||
string DefaultRoomKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the application URL for the controller
|
||||
/// </summary>
|
||||
/// <param name="url">The application URL</param>
|
||||
void SetAppUrl(string url);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the controller uses a direct server connection
|
||||
/// </summary>
|
||||
bool UseDirectServer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the controller is a Zoom Room controller
|
||||
/// </summary>
|
||||
bool ZoomRoomController { get; }
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
private static void ListDevices(string s)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse($"{Devices.Count} Devices registered with Device Manager:");
|
||||
CrestronConsole.ConsoleCommandResponse($"{Devices.Count} Devices registered with Device Manager:\r\n");
|
||||
|
||||
var sorted = Devices.Values.ToList();
|
||||
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
|
||||
@@ -210,7 +210,7 @@ namespace PepperDash.Essentials.Core
|
||||
foreach (var d in sorted)
|
||||
{
|
||||
var name = d is IKeyName ? (d as IKeyName).Name : "---";
|
||||
CrestronConsole.ConsoleCommandResponse($" [{d.Key}] {name}");
|
||||
CrestronConsole.ConsoleCommandResponse($" [{d.Key}] {name}\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,28 +219,17 @@ namespace PepperDash.Essentials.Core
|
||||
var dev = GetDeviceForKey(devKey);
|
||||
if (dev == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Device '{0}' not found", devKey);
|
||||
CrestronConsole.ConsoleCommandResponse($"Device '{devKey}' not found\r\n");
|
||||
return;
|
||||
}
|
||||
if (!(dev is IHasFeedback statusDev))
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Device '{0}' does not have visible feedbacks", devKey);
|
||||
CrestronConsole.ConsoleCommandResponse($"Device '{devKey}' does not have visible feedbacks\r\n");
|
||||
return;
|
||||
}
|
||||
statusDev.DumpFeedbacksToConsole(true);
|
||||
}
|
||||
|
||||
//static void ListDeviceCommands(string devKey)
|
||||
//{
|
||||
// var dev = GetDeviceForKey(devKey);
|
||||
// if (dev == null)
|
||||
// {
|
||||
// Debug.LogMessage(LogEventLevel.Information, "Device '{0}' not found", devKey);
|
||||
// return;
|
||||
// }
|
||||
// Debug.LogMessage(LogEventLevel.Information, "This needs to be reworked. Stay tuned.", devKey);
|
||||
//}
|
||||
|
||||
private static void ListDeviceCommStatuses(string input)
|
||||
{
|
||||
|
||||
@@ -250,12 +239,6 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//static void DoDeviceCommand(string command)
|
||||
//{
|
||||
// Debug.LogMessage(LogEventLevel.Information, "Not yet implemented. Stay tuned");
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// AddDevice method
|
||||
/// </summary>
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Core
|
||||
public List<string> TypeNames { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The method that will build the device
|
||||
/// Build the device using the configuration
|
||||
/// </summary>
|
||||
/// <param name="dc">The device config</param>
|
||||
/// <returns>An instance of the device</returns>
|
||||
|
||||
@@ -1,65 +1,90 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasFeedback
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Defines the contract for IHasFeedback
|
||||
/// </summary>
|
||||
public interface IHasFeedback : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// This method shall return a list of all Output objects on a device,
|
||||
/// This method returns a list of all Output objects on a device,
|
||||
/// including all "aggregate" devices.
|
||||
/// </summary>
|
||||
FeedbackCollection<Feedback> Feedbacks { get; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for IHasFeedback
|
||||
/// </summary>
|
||||
public static class IHasFeedbackExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the feedback type name for sorting purposes
|
||||
/// </summary>
|
||||
/// <param name="feedback">The feedback to get the type name for</param>
|
||||
/// <returns>A string representing the feedback type</returns>
|
||||
private static string GetFeedbackTypeName(Feedback feedback)
|
||||
{
|
||||
if (feedback is BoolFeedback)
|
||||
return "boolean";
|
||||
else if (feedback is IntFeedback)
|
||||
return "integer";
|
||||
else if (feedback is StringFeedback)
|
||||
return "string";
|
||||
else
|
||||
return feedback.GetType().Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dumps the feedbacks to the console
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="getCurrentStates"></param>
|
||||
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
||||
{
|
||||
Type t = source.GetType();
|
||||
// get the properties and set them into a new collection of NameType wrappers
|
||||
var props = t.GetProperties().Select(p => new PropertyNameType(p, t));
|
||||
|
||||
var feedbacks = source.Feedbacks;
|
||||
if (feedbacks != null)
|
||||
|
||||
if (feedbacks == null || feedbacks.Count == 0)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, source, "\n\nAvailable feedbacks:");
|
||||
foreach (var f in feedbacks)
|
||||
{
|
||||
string val = "";
|
||||
string type = "";
|
||||
if (getCurrentStates)
|
||||
{
|
||||
if (f is BoolFeedback)
|
||||
{
|
||||
val = f.BoolValue.ToString();
|
||||
type = "boolean";
|
||||
}
|
||||
else if (f is IntFeedback)
|
||||
{
|
||||
val = f.IntValue.ToString();
|
||||
type = "integer";
|
||||
}
|
||||
else if (f is StringFeedback)
|
||||
{
|
||||
val = f.StringValue;
|
||||
type = "string";
|
||||
}
|
||||
}
|
||||
Debug.LogMessage(LogEventLevel.Information, "{0,-12} {1, -25} {2}", type,
|
||||
(string.IsNullOrEmpty(f.Key) ? "-no key-" : f.Key), val);
|
||||
}
|
||||
CrestronConsole.ConsoleCommandResponse("No available feedbacks\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CrestronConsole.ConsoleCommandResponse("Available feedbacks:\r\n");
|
||||
|
||||
// Sort feedbacks by type first, then by key
|
||||
var sortedFeedbacks = feedbacks.OrderBy(f => GetFeedbackTypeName(f)).ThenBy(f => string.IsNullOrEmpty(f.Key) ? "" : f.Key);
|
||||
|
||||
foreach (var feedback in sortedFeedbacks)
|
||||
{
|
||||
string value = "";
|
||||
string type = "";
|
||||
if (getCurrentStates)
|
||||
{
|
||||
if (feedback is BoolFeedback)
|
||||
{
|
||||
value = feedback.BoolValue.ToString();
|
||||
type = "boolean";
|
||||
}
|
||||
else if (feedback is IntFeedback)
|
||||
{
|
||||
value = feedback.IntValue.ToString();
|
||||
type = "integer";
|
||||
}
|
||||
else if (feedback is StringFeedback)
|
||||
{
|
||||
value = feedback.StringValue;
|
||||
type = "string";
|
||||
}
|
||||
}
|
||||
CrestronConsole.ConsoleCommandResponse($" {type,-12} {(string.IsNullOrEmpty(feedback.Key) ? "-no key-" : feedback.Key),-25} {value}\r\n");
|
||||
}
|
||||
else
|
||||
Debug.LogMessage(LogEventLevel.Information, source, "No available outputs:");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,12 @@ namespace PepperDash.Essentials.Core
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to hide this scenario in the UI.
|
||||
/// </summary>
|
||||
[JsonProperty("hideInUi", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool HideInUi { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of partition states.
|
||||
/// </summary>
|
||||
|
||||
@@ -109,6 +109,12 @@ namespace PepperDash.Essentials.Core
|
||||
[JsonProperty("isActive")]
|
||||
bool IsActive { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this scenario should be hidden in the UI.
|
||||
/// </summary>
|
||||
[JsonProperty("hideInUi")]
|
||||
bool HideInUi { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Activates this room combination scenario
|
||||
/// </summary>
|
||||
|
||||
@@ -14,18 +14,40 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
private RoomCombinationScenarioConfig _config;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the key associated with the object.
|
||||
/// </summary>
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name associated with the object.
|
||||
/// </summary>
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("partitionStates")]
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether to hide this scenario in the UI.
|
||||
/// </summary>
|
||||
///
|
||||
[JsonProperty("hideInUi")]
|
||||
|
||||
public bool HideInUi
|
||||
{
|
||||
get { return _config.HideInUi; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the PartitionStates
|
||||
/// </summary>
|
||||
///
|
||||
[JsonProperty("partitionStates")]
|
||||
|
||||
public List<PartitionState> PartitionStates { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines which UI devices get mapped to which room in this scenario. The Key should be the key of the UI device and the Value should be the key of the room to map to
|
||||
/// </summary>
|
||||
[JsonProperty("uiMap")]
|
||||
public Dictionary<string, string> UiMap { get; set; }
|
||||
|
||||
|
||||
@@ -9,11 +9,11 @@ using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a EssentialsRoomConfigHelper
|
||||
/// </summary>
|
||||
public class EssentialsRoomConfigHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a EssentialsRoomConfigHelper
|
||||
/// </summary>
|
||||
public class EssentialsRoomConfigHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// GetEmergency method
|
||||
/// </summary>
|
||||
@@ -31,100 +31,100 @@ namespace PepperDash.Essentials.Room.Config
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="props"></param>
|
||||
/// <param name="room"></param>
|
||||
/// <returns></returns>
|
||||
/// <summary>
|
||||
/// GetMicrophonePrivacy method
|
||||
/// </summary>
|
||||
public static MicrophonePrivacyController GetMicrophonePrivacy(
|
||||
EssentialsRoomPropertiesConfig props, IPrivacy room)
|
||||
{
|
||||
var microphonePrivacy = props.MicrophonePrivacy;
|
||||
if (microphonePrivacy == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Cannot create microphone privacy with null properties");
|
||||
return null;
|
||||
}
|
||||
// Get the MicrophonePrivacy device from the device manager
|
||||
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as MicrophonePrivacyController);
|
||||
// Set this room as the IPrivacy device
|
||||
if (mP == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "ERROR: Selected device {0} is not MicrophonePrivacyController", props.MicrophonePrivacy.DeviceKey);
|
||||
return null;
|
||||
}
|
||||
mP.SetPrivacyDevice(room);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="props"></param>
|
||||
/// <param name="room"></param>
|
||||
/// <returns></returns>
|
||||
/// <summary>
|
||||
/// GetMicrophonePrivacy method
|
||||
/// </summary>
|
||||
public static MicrophonePrivacyController GetMicrophonePrivacy(
|
||||
EssentialsRoomPropertiesConfig props, IPrivacy room)
|
||||
{
|
||||
var microphonePrivacy = props.MicrophonePrivacy;
|
||||
if (microphonePrivacy == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Cannot create microphone privacy with null properties");
|
||||
return null;
|
||||
}
|
||||
// Get the MicrophonePrivacy device from the device manager
|
||||
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as MicrophonePrivacyController);
|
||||
// Set this room as the IPrivacy device
|
||||
if (mP == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "ERROR: Selected device {0} is not MicrophonePrivacyController", props.MicrophonePrivacy.DeviceKey);
|
||||
return null;
|
||||
}
|
||||
mP.SetPrivacyDevice(room);
|
||||
|
||||
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
|
||||
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
|
||||
|
||||
if (behaviour == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "WARNING: No behaviour defined for MicrophonePrivacyController");
|
||||
return null;
|
||||
}
|
||||
if (behaviour == "trackroomstate")
|
||||
{
|
||||
// Tie LED enable to room power state
|
||||
if (behaviour == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "WARNING: No behaviour defined for MicrophonePrivacyController");
|
||||
return null;
|
||||
}
|
||||
if (behaviour == "trackroomstate")
|
||||
{
|
||||
// Tie LED enable to room power state
|
||||
var essRoom = room as IEssentialsRoom;
|
||||
essRoom.OnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
{
|
||||
if (essRoom.OnFeedback.BoolValue)
|
||||
mP.EnableLeds = true;
|
||||
else
|
||||
mP.EnableLeds = false;
|
||||
};
|
||||
mP.EnableLeds = true;
|
||||
else
|
||||
mP.EnableLeds = false;
|
||||
};
|
||||
|
||||
mP.EnableLeds = essRoom.OnFeedback.BoolValue;
|
||||
}
|
||||
else if (behaviour == "trackcallstate")
|
||||
{
|
||||
// Tie LED enable to room power state
|
||||
}
|
||||
else if (behaviour == "trackcallstate")
|
||||
{
|
||||
// Tie LED enable to room power state
|
||||
var inCallRoom = room as IHasInCallFeedback;
|
||||
inCallRoom.InCallFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
{
|
||||
if (inCallRoom.InCallFeedback.BoolValue)
|
||||
mP.EnableLeds = true;
|
||||
else
|
||||
mP.EnableLeds = false;
|
||||
};
|
||||
mP.EnableLeds = true;
|
||||
else
|
||||
mP.EnableLeds = false;
|
||||
};
|
||||
|
||||
mP.EnableLeds = inCallRoom.InCallFeedback.BoolValue;
|
||||
}
|
||||
}
|
||||
|
||||
return mP;
|
||||
}
|
||||
|
||||
}
|
||||
return mP;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a EssentialsRoomPropertiesConfig
|
||||
/// </summary>
|
||||
public class EssentialsRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("addresses")]
|
||||
public EssentialsRoomAddressPropertiesConfig Addresses { get; set; }
|
||||
}
|
||||
|
||||
[JsonProperty("description")]
|
||||
public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// Represents a EssentialsRoomPropertiesConfig
|
||||
/// </summary>
|
||||
public class EssentialsRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("addresses")]
|
||||
public EssentialsRoomAddressPropertiesConfig Addresses { get; set; }
|
||||
|
||||
[JsonProperty("emergency")]
|
||||
public EssentialsRoomEmergencyConfig Emergency { get; set; }
|
||||
[JsonProperty("description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[JsonProperty("help")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Help
|
||||
/// </summary>
|
||||
public EssentialsHelpPropertiesConfig Help { get; set; }
|
||||
[JsonProperty("emergency")]
|
||||
public EssentialsRoomEmergencyConfig Emergency { get; set; }
|
||||
|
||||
[JsonProperty("helpMessage")]
|
||||
/// <summary>
|
||||
/// Gets or sets the HelpMessage
|
||||
/// </summary>
|
||||
public string HelpMessage { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Help
|
||||
/// </summary>
|
||||
[JsonProperty("help")]
|
||||
public EssentialsHelpPropertiesConfig Help { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HelpMessage
|
||||
/// </summary>
|
||||
[JsonProperty("helpMessage")]
|
||||
public string HelpMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Read this value to get the help message. It checks for the old and new config format.
|
||||
@@ -133,94 +133,94 @@ namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
get
|
||||
{
|
||||
if(Help != null && !string.IsNullOrEmpty(Help.Message))
|
||||
if (Help != null && !string.IsNullOrEmpty(Help.Message))
|
||||
{
|
||||
return Help.Message;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HelpMessage;
|
||||
return HelpMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("environment")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Environment
|
||||
/// </summary>
|
||||
public EssentialsEnvironmentPropertiesConfig Environment { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Environment
|
||||
/// </summary>
|
||||
[JsonProperty("environment")]
|
||||
public EssentialsEnvironmentPropertiesConfig Environment { get; set; }
|
||||
|
||||
[JsonProperty("logo")]
|
||||
/// <summary>
|
||||
/// Gets or sets the LogoLight
|
||||
/// </summary>
|
||||
public EssentialsLogoPropertiesConfig LogoLight { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the LogoLight
|
||||
/// </summary>
|
||||
[JsonProperty("logo")]
|
||||
public EssentialsLogoPropertiesConfig LogoLight { get; set; }
|
||||
|
||||
[JsonProperty("logoDark")]
|
||||
/// <summary>
|
||||
/// Gets or sets the LogoDark
|
||||
/// </summary>
|
||||
[JsonProperty("logoDark")]
|
||||
public EssentialsLogoPropertiesConfig LogoDark { get; set; }
|
||||
|
||||
[JsonProperty("microphonePrivacy")]
|
||||
/// <summary>
|
||||
/// Gets or sets the MicrophonePrivacy
|
||||
/// </summary>
|
||||
public EssentialsRoomMicrophonePrivacyConfig MicrophonePrivacy { get; set; }
|
||||
|
||||
[JsonProperty("occupancy")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Occupancy
|
||||
/// </summary>
|
||||
public EssentialsRoomOccSensorConfig Occupancy { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the MicrophonePrivacy
|
||||
/// </summary>
|
||||
[JsonProperty("microphonePrivacy")]
|
||||
public EssentialsRoomMicrophonePrivacyConfig MicrophonePrivacy { get; set; }
|
||||
|
||||
[JsonProperty("oneButtonMeeting")]
|
||||
/// <summary>
|
||||
/// Gets or sets the OneButtonMeeting
|
||||
/// </summary>
|
||||
public EssentialsOneButtonMeetingPropertiesConfig OneButtonMeeting { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Occupancy
|
||||
/// </summary>
|
||||
[JsonProperty("occupancy")]
|
||||
public EssentialsRoomOccSensorConfig Occupancy { get; set; }
|
||||
|
||||
[JsonProperty("shutdownVacancySeconds")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ShutdownVacancySeconds
|
||||
/// </summary>
|
||||
public int ShutdownVacancySeconds { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the OneButtonMeeting
|
||||
/// </summary>
|
||||
[JsonProperty("oneButtonMeeting")]
|
||||
public EssentialsOneButtonMeetingPropertiesConfig OneButtonMeeting { get; set; }
|
||||
|
||||
[JsonProperty("shutdownPromptSeconds")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ShutdownPromptSeconds
|
||||
/// </summary>
|
||||
public int ShutdownPromptSeconds { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the ShutdownVacancySeconds
|
||||
/// </summary>
|
||||
[JsonProperty("shutdownVacancySeconds")]
|
||||
public int ShutdownVacancySeconds { get; set; }
|
||||
|
||||
[JsonProperty("tech")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Tech
|
||||
/// </summary>
|
||||
public EssentialsRoomTechConfig Tech { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the ShutdownPromptSeconds
|
||||
/// </summary>
|
||||
[JsonProperty("shutdownPromptSeconds")]
|
||||
public int ShutdownPromptSeconds { get; set; }
|
||||
|
||||
[JsonProperty("volumes")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Volumes
|
||||
/// </summary>
|
||||
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Tech
|
||||
/// </summary>
|
||||
[JsonProperty("tech")]
|
||||
public EssentialsRoomTechConfig Tech { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Volumes
|
||||
/// </summary>
|
||||
[JsonProperty("volumes")]
|
||||
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
||||
|
||||
[JsonProperty("fusion")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Fusion
|
||||
/// </summary>
|
||||
[JsonProperty("fusion")]
|
||||
public EssentialsRoomFusionConfig Fusion { get; set; }
|
||||
|
||||
[JsonProperty("essentialsRoomUiBehaviorConfig", NullValueHandling=NullValueHandling.Ignore)]
|
||||
/// <summary>
|
||||
/// Gets or sets the UiBehavior
|
||||
/// </summary>
|
||||
[JsonProperty("essentialsRoomUiBehaviorConfig", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
|
||||
|
||||
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ZeroVolumeWhenSwtichingVolumeDevices
|
||||
/// </summary>
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the ZeroVolumeWhenSwtichingVolumeDevices
|
||||
/// </summary>
|
||||
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if this room represents a combination of other rooms
|
||||
@@ -236,7 +236,7 @@ namespace PepperDash.Essentials.Room.Config
|
||||
LogoLight = new EssentialsLogoPropertiesConfig();
|
||||
LogoDark = new EssentialsLogoPropertiesConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a EssentialsRoomUiBehaviorConfig
|
||||
@@ -327,15 +327,15 @@ namespace PepperDash.Essentials.Room.Config
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a EssentialsEnvironmentPropertiesConfig
|
||||
/// </summary>
|
||||
public class EssentialsEnvironmentPropertiesConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Enabled
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
/// <summary>
|
||||
/// Represents a EssentialsEnvironmentPropertiesConfig
|
||||
/// </summary>
|
||||
public class EssentialsEnvironmentPropertiesConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Enabled
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
[JsonProperty("deviceKeys")]
|
||||
/// <summary>
|
||||
@@ -348,7 +348,7 @@ namespace PepperDash.Essentials.Room.Config
|
||||
DeviceKeys = new List<string>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a EssentialsRoomFusionConfig
|
||||
@@ -359,7 +359,7 @@ namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
try
|
||||
{
|
||||
return Convert.ToUInt32(IpId, 16);
|
||||
}
|
||||
@@ -367,7 +367,7 @@ namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
throw new FormatException(string.Format("ERROR:Unable to convert IP ID: {0} to hex. Error:\n{1}", IpId));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,17 +390,17 @@ namespace PepperDash.Essentials.Room.Config
|
||||
/// </summary>
|
||||
public class EssentialsRoomMicrophonePrivacyConfig
|
||||
{
|
||||
[JsonProperty("deviceKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the DeviceKey
|
||||
/// </summary>
|
||||
public string DeviceKey { get; set; }
|
||||
[JsonProperty("deviceKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the DeviceKey
|
||||
/// </summary>
|
||||
public string DeviceKey { get; set; }
|
||||
|
||||
[JsonProperty("behaviour")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Behaviour
|
||||
/// </summary>
|
||||
public string Behaviour { get; set; }
|
||||
[JsonProperty("behaviour")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Behaviour
|
||||
/// </summary>
|
||||
public string Behaviour { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -408,23 +408,23 @@ namespace PepperDash.Essentials.Room.Config
|
||||
/// </summary>
|
||||
public class EssentialsHelpPropertiesConfig
|
||||
{
|
||||
[JsonProperty("message")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Message
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
[JsonProperty("message")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Message
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
[JsonProperty("showCallButton")]
|
||||
public bool ShowCallButton { get; set; }
|
||||
|
||||
/// <summary>
|
||||
[JsonProperty("showCallButton")]
|
||||
public bool ShowCallButton { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defaults to "Call Help Desk"
|
||||
/// </summary>
|
||||
[JsonProperty("callButtonText")]
|
||||
/// <summary>
|
||||
/// Gets or sets the CallButtonText
|
||||
/// </summary>
|
||||
public string CallButtonText { get; set; }
|
||||
[JsonProperty("callButtonText")]
|
||||
/// <summary>
|
||||
/// Gets or sets the CallButtonText
|
||||
/// </summary>
|
||||
public string CallButtonText { get; set; }
|
||||
|
||||
public EssentialsHelpPropertiesConfig()
|
||||
{
|
||||
@@ -437,23 +437,23 @@ namespace PepperDash.Essentials.Room.Config
|
||||
/// </summary>
|
||||
public class EssentialsOneButtonMeetingPropertiesConfig
|
||||
{
|
||||
[JsonProperty("enable")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Enable
|
||||
/// </summary>
|
||||
public bool Enable { get; set; }
|
||||
[JsonProperty("enable")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Enable
|
||||
/// </summary>
|
||||
public bool Enable { get; set; }
|
||||
}
|
||||
|
||||
public class EssentialsRoomAddressPropertiesConfig
|
||||
{
|
||||
[JsonProperty("phoneNumber")]
|
||||
public string PhoneNumber { get; set; }
|
||||
[JsonProperty("phoneNumber")]
|
||||
public string PhoneNumber { get; set; }
|
||||
|
||||
[JsonProperty("sipAddress")]
|
||||
/// <summary>
|
||||
/// Gets or sets the SipAddress
|
||||
/// </summary>
|
||||
public string SipAddress { get; set; }
|
||||
[JsonProperty("sipAddress")]
|
||||
/// <summary>
|
||||
/// Gets or sets the SipAddress
|
||||
/// </summary>
|
||||
public string SipAddress { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -462,14 +462,14 @@ namespace PepperDash.Essentials.Room.Config
|
||||
/// </summary>
|
||||
public class EssentialsLogoPropertiesConfig
|
||||
{
|
||||
[JsonProperty("type")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Type
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
[JsonProperty("type")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Type
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
[JsonProperty("url")]
|
||||
public string Url { get; set; }
|
||||
[JsonProperty("url")]
|
||||
public string Url { get; set; }
|
||||
/// <summary>
|
||||
/// GetLogoUrlLight method
|
||||
/// </summary>
|
||||
@@ -478,7 +478,7 @@ namespace PepperDash.Essentials.Room.Config
|
||||
if (Type == "url")
|
||||
return Url;
|
||||
if (Type == "system")
|
||||
return string.Format("http://{0}:8080/logo.png",
|
||||
return string.Format("http://{0}:8080/logo.png",
|
||||
CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0));
|
||||
return null;
|
||||
}
|
||||
@@ -502,22 +502,22 @@ namespace PepperDash.Essentials.Room.Config
|
||||
/// </summary>
|
||||
public class EssentialsRoomOccSensorConfig
|
||||
{
|
||||
[JsonProperty("deviceKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the DeviceKey
|
||||
/// </summary>
|
||||
public string DeviceKey { get; set; }
|
||||
[JsonProperty("deviceKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the DeviceKey
|
||||
/// </summary>
|
||||
public string DeviceKey { get; set; }
|
||||
|
||||
[JsonProperty("timeoutMinutes")]
|
||||
public int TimeoutMinutes { get; set; }
|
||||
[JsonProperty("timeoutMinutes")]
|
||||
public int TimeoutMinutes { get; set; }
|
||||
}
|
||||
|
||||
public class EssentialsRoomTechConfig
|
||||
{
|
||||
[JsonProperty("password")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Password
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
}
|
||||
public class EssentialsRoomTechConfig
|
||||
{
|
||||
[JsonProperty("password")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Password
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -14,14 +14,14 @@ using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
////*****************************************************************************
|
||||
/// <summary>
|
||||
/// Base class for all subpage reference list controllers
|
||||
/// </summary>
|
||||
//public class SubpageReferenceListController
|
||||
//{
|
||||
// public SubpageReferenceList TheList { get; protected set; }
|
||||
//}
|
||||
////*****************************************************************************
|
||||
///// <summary>
|
||||
///// Base class for all subpage reference list controllers
|
||||
///// </summary>
|
||||
//public class SubpageReferenceListController
|
||||
//{
|
||||
// public SubpageReferenceList TheList { get; protected set; }
|
||||
//}
|
||||
|
||||
//*****************************************************************************
|
||||
/// <summary>
|
||||
@@ -34,26 +34,26 @@ namespace PepperDash.Essentials.Core
|
||||
public ushort Count
|
||||
{
|
||||
get { return SetNumberOfItemsSig.UShortValue; }
|
||||
set { SetNumberOfItemsSig.UShortValue = value; }
|
||||
set { SetNumberOfItemsSig.UShortValue = value; }
|
||||
}
|
||||
public ushort MaxDefinedItems { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ScrollToItemSig
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the ScrollToItemSig
|
||||
/// </summary>
|
||||
public UShortInputSig ScrollToItemSig { get; private set; }
|
||||
UShortInputSig SetNumberOfItemsSig;
|
||||
/// <summary>
|
||||
/// Gets or sets the BoolIncrement
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the BoolIncrement
|
||||
/// </summary>
|
||||
public uint BoolIncrement { get; protected set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the UShortIncrement
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the UShortIncrement
|
||||
/// </summary>
|
||||
public uint UShortIncrement { get; protected set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the StringIncrement
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets or sets the StringIncrement
|
||||
/// </summary>
|
||||
public uint StringIncrement { get; protected set; }
|
||||
|
||||
protected readonly SmartObject SRL;
|
||||
@@ -87,8 +87,8 @@ namespace PepperDash.Essentials.Core
|
||||
SRL.SigChange += new SmartObjectSigChangeEventHandler(SRL_SigChange);
|
||||
}
|
||||
else
|
||||
Debug.LogMessage(LogEventLevel.Information, "ERROR: TriList 0x{0:X2} Cannot load smart object {1}. Verify correct SGD file is loaded",
|
||||
triList.ID, smartObjectId);
|
||||
Debug.LogMessage(LogEventLevel.Information, "ERROR: TriList 0x{0:X2} Cannot load smart object {1}. Verify correct SGD file is loaded",
|
||||
triList.ID, smartObjectId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -96,17 +96,17 @@ namespace PepperDash.Essentials.Core
|
||||
/// DOES NOT adjust Count
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <summary>
|
||||
/// AddItem method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// AddItem method
|
||||
/// </summary>
|
||||
public void AddItem(SubpageReferenceListItem item)
|
||||
{
|
||||
Items.Add(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Clear method
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
// If a line item needs to disconnect an CueActionPair or do something to release RAM
|
||||
@@ -116,12 +116,12 @@ namespace PepperDash.Essentials.Core
|
||||
// Clean up the SRL
|
||||
Count = 1;
|
||||
|
||||
ScrollToItemSig.UShortValue = 1;
|
||||
ScrollToItemSig.UShortValue = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Refresh method
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
foreach (var item in Items) item.Refresh();
|
||||
@@ -157,7 +157,7 @@ namespace PepperDash.Essentials.Core
|
||||
public UShortOutputSig GetUShortOutputSig(uint index, uint sigNum)
|
||||
{
|
||||
if (sigNum > UShortIncrement) return null;
|
||||
return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetUShortOutputSigName(index, sigNum)));
|
||||
return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetUShortOutputSigName(index, sigNum)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -172,7 +172,7 @@ namespace PepperDash.Essentials.Core
|
||||
public StringOutputSig GetStringOutputSig(uint index, uint sigNum)
|
||||
{
|
||||
if (sigNum > StringIncrement) return null;
|
||||
return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetStringOutputSigName(index, sigNum)));
|
||||
return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetStringOutputSigName(index, sigNum)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -263,9 +263,9 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
/// <param name="currentDevice"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <summary>
|
||||
/// SRL_SigChange method
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// SRL_SigChange method
|
||||
/// </summary>
|
||||
public static void SRL_SigChange(GenericBase currentDevice, SmartObjectEventArgs args)
|
||||
{
|
||||
var uo = args.Sig.UserObject;
|
||||
|
||||
@@ -6,9 +6,9 @@ using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a ModalDialog
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Represents a ModalDialog
|
||||
/// </summary>
|
||||
public class ModalDialog
|
||||
{
|
||||
/// <summary>
|
||||
@@ -19,10 +19,10 @@ namespace PepperDash.Essentials.Core
|
||||
/// Bool press 3992
|
||||
/// </summary>
|
||||
public const uint Button2Join = 3992;
|
||||
/// <summary>
|
||||
/// 3993
|
||||
/// </summary>
|
||||
public const uint CancelButtonJoin = 3993;
|
||||
/// <summary>
|
||||
/// 3993
|
||||
/// </summary>
|
||||
public const uint CancelButtonJoin = 3993;
|
||||
/// <summary>
|
||||
///For visibility of single button. Bool feedback 3994
|
||||
/// </summary>
|
||||
@@ -35,19 +35,19 @@ namespace PepperDash.Essentials.Core
|
||||
/// Shows the timer guage if in use. Bool feedback 3996
|
||||
/// </summary>
|
||||
public const uint TimerVisibleJoin = 3996;
|
||||
/// <summary>
|
||||
/// Visibility join to show "X" button 3997
|
||||
/// </summary>
|
||||
public const uint CancelVisibleJoin = 3997;
|
||||
/// <summary>
|
||||
/// Visibility join to show "X" button 3997
|
||||
/// </summary>
|
||||
public const uint CancelVisibleJoin = 3997;
|
||||
/// <summary>
|
||||
/// Shows the modal subpage. Boolean feeback join 3999
|
||||
/// </summary>
|
||||
public const uint ModalVisibleJoin = 3999;
|
||||
|
||||
/// <summary>
|
||||
/// The seconds value of the countdown timer. Ushort join 3991
|
||||
/// </summary>
|
||||
//public const uint TimerSecondsJoin = 3991;
|
||||
///// <summary>
|
||||
///// The seconds value of the countdown timer. Ushort join 3991
|
||||
///// </summary>
|
||||
//public const uint TimerSecondsJoin = 3991;
|
||||
/// <summary>
|
||||
/// The full ushort value of the countdown timer for a gauge. Ushort join 3992
|
||||
/// </summary>
|
||||
@@ -77,15 +77,15 @@ namespace PepperDash.Essentials.Core
|
||||
/// <summary>
|
||||
/// Returns true when modal is showing
|
||||
/// </summary>
|
||||
public bool ModalIsVisible
|
||||
{
|
||||
get { return TriList.BooleanInput[ModalVisibleJoin].BoolValue; }
|
||||
public bool ModalIsVisible
|
||||
{
|
||||
get { return TriList.BooleanInput[ModalVisibleJoin].BoolValue; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool CanCancel { get; private set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool CanCancel { get; private set; }
|
||||
|
||||
|
||||
BasicTriList TriList;
|
||||
@@ -103,10 +103,10 @@ namespace PepperDash.Essentials.Core
|
||||
TriList = triList;
|
||||
// Attach actions to buttons
|
||||
|
||||
triList.SetSigFalseAction(Button1Join, () => OnModalComplete(1));
|
||||
triList.SetSigFalseAction(Button1Join, () => OnModalComplete(1));
|
||||
triList.SetSigFalseAction(Button2Join, () => OnModalComplete(2));
|
||||
triList.SetSigFalseAction(CancelButtonJoin, () => { if (CanCancel) CancelDialog(); });
|
||||
CanCancel = true;
|
||||
triList.SetSigFalseAction(CancelButtonJoin, () => { if (CanCancel) CancelDialog(); });
|
||||
CanCancel = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -117,7 +117,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// <param name="decreasingGauge">If the progress bar gauge needs to count down instead of up</param>
|
||||
/// <param name="completeAction">The action to run when the dialog is dismissed. Parameter will be 1 or 2 if button pressed, or 0 if dialog times out</param>
|
||||
/// <returns>True when modal is created.</returns>
|
||||
public bool PresentModalDialog(uint numberOfButtons, string title, string iconName,
|
||||
public bool PresentModalDialog(uint numberOfButtons, string title, string iconName,
|
||||
string message, string button1Text,
|
||||
string button2Text, bool showGauge, bool showCancel, Action<uint> completeAction)
|
||||
{
|
||||
@@ -151,15 +151,15 @@ namespace PepperDash.Essentials.Core
|
||||
TriList.StringInput[Button2TextJoin].StringValue = button2Text;
|
||||
}
|
||||
// Show/hide guage
|
||||
TriList.BooleanInput[TimerVisibleJoin].BoolValue = showGauge;
|
||||
|
||||
CanCancel = showCancel;
|
||||
TriList.BooleanInput[CancelVisibleJoin].BoolValue = showCancel;
|
||||
TriList.BooleanInput[TimerVisibleJoin].BoolValue = showGauge;
|
||||
|
||||
CanCancel = showCancel;
|
||||
TriList.BooleanInput[CancelVisibleJoin].BoolValue = showCancel;
|
||||
|
||||
//Reveal and activate
|
||||
TriList.BooleanInput[ModalVisibleJoin].BoolValue = true;
|
||||
|
||||
WakePanel();
|
||||
WakePanel();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -167,48 +167,48 @@ namespace PepperDash.Essentials.Core
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WakePanel method
|
||||
/// </summary>
|
||||
public void WakePanel()
|
||||
{
|
||||
try
|
||||
{
|
||||
var panel = TriList as TswFt5Button;
|
||||
|
||||
if (panel != null && panel.ExtenderSystemReservedSigs.BacklightOffFeedback.BoolValue)
|
||||
panel.ExtenderSystemReservedSigs.BacklightOn();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Error Waking Panel. Maybe testing with Xpanel?");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CancelDialog method
|
||||
/// </summary>
|
||||
public void CancelDialog()
|
||||
/// <summary>
|
||||
/// WakePanel method
|
||||
/// </summary>
|
||||
public void WakePanel()
|
||||
{
|
||||
OnModalComplete(0);
|
||||
try
|
||||
{
|
||||
var panel = TriList as TswFt5Button;
|
||||
|
||||
if (panel != null && panel.ExtenderSystemReservedSigs.BacklightOffFeedback.BoolValue)
|
||||
panel.ExtenderSystemReservedSigs.BacklightOn();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Error Waking Panel. Maybe testing with Xpanel?");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides dialog. Fires no action
|
||||
/// </summary>
|
||||
public void HideDialog()
|
||||
{
|
||||
TriList.BooleanInput[ModalVisibleJoin].BoolValue = false;
|
||||
}
|
||||
/// <summary>
|
||||
/// CancelDialog method
|
||||
/// </summary>
|
||||
public void CancelDialog()
|
||||
{
|
||||
OnModalComplete(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides dialog. Fires no action
|
||||
/// </summary>
|
||||
public void HideDialog()
|
||||
{
|
||||
TriList.BooleanInput[ModalVisibleJoin].BoolValue = false;
|
||||
}
|
||||
|
||||
// When the modal is cleared or times out, clean up the various bits
|
||||
void OnModalComplete(uint buttonNum)
|
||||
{
|
||||
TriList.BooleanInput[ModalVisibleJoin].BoolValue = false;
|
||||
|
||||
var action = ModalCompleteAction;
|
||||
if (action != null)
|
||||
action(buttonNum);
|
||||
var action = ModalCompleteAction;
|
||||
if (action != null)
|
||||
action(buttonNum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user