mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-22 16:15:08 +00:00
Compare commits
84 Commits
v2.18.0-fe
...
v2.20.7-wo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b6f1907c6 | ||
|
|
54da30a650 | ||
|
|
475c16b9c2 | ||
|
|
81aab0b8c1 | ||
|
|
770d7fa0ea | ||
|
|
5f292cacd9 | ||
|
|
2fbc32947c | ||
|
|
c06b57a5f9 | ||
|
|
6d64fffc50 | ||
|
|
0c4ebdaf1d | ||
|
|
2c49fb9321 | ||
|
|
c55de61da9 | ||
|
|
42444ede0a | ||
|
|
3d50f5f5ac | ||
|
|
11d62aebe1 | ||
|
|
edc10a9c2a | ||
|
|
9be5823956 | ||
|
|
35371dde22 | ||
|
|
d3ceb4d7e7 | ||
|
|
a782b57100 | ||
|
|
1360de599f | ||
|
|
fd95f5fed1 | ||
|
|
9426dff5df | ||
|
|
0d083e63c6 | ||
|
|
6ed7c96ec7 | ||
|
|
314570d6c3 | ||
|
|
ff609dfecd | ||
|
|
666be5ae59 | ||
|
|
bfc9b7e7fa | ||
|
|
b02e952765 | ||
|
|
72861a5097 | ||
|
|
44ed067f4d | ||
|
|
faa2169baf | ||
|
|
fd40b0c6d1 | ||
|
|
afcddad1cc | ||
|
|
c4cf8f13e9 | ||
|
|
c852f87a27 | ||
|
|
071174fa7d | ||
|
|
da0f28a10c | ||
|
|
0538a304ed | ||
|
|
705c5db237 | ||
|
|
2e95f5337e | ||
|
|
ba576180a7 | ||
|
|
92c9db8237 | ||
|
|
c4d064965f | ||
|
|
f27965ac29 | ||
|
|
3ce282e2db | ||
|
|
32a332a6e2 | ||
|
|
151a90c9be | ||
|
|
89e893b3b7 | ||
|
|
d01eb03890 | ||
|
|
16c92afabb | ||
|
|
dff5d2d32e | ||
|
|
317bde3814 | ||
|
|
8bab3dc966 | ||
|
|
514ac850ca | ||
|
|
44432f7a41 | ||
|
|
99253b30c2 | ||
|
|
bf248fe33e | ||
|
|
2f44040e4f | ||
|
|
10399a1be8 | ||
|
|
5409db193c | ||
|
|
f1ce54a524 | ||
|
|
7c72a0d905 | ||
|
|
5d5e78629e | ||
|
|
dab5484d6e | ||
|
|
5c35a3be45 | ||
|
|
6cb98e12fa | ||
|
|
608601990b | ||
|
|
3e0f318f7f | ||
|
|
98d0cc8fdc | ||
|
|
c557c6cdd6 | ||
|
|
8525134ae7 | ||
|
|
1197b15a33 | ||
|
|
ea6a7568fc | ||
|
|
3a2a059ce1 | ||
|
|
f9d9df9d5c | ||
|
|
c284c4275f | ||
|
|
0418f8a7cc | ||
|
|
a5d409e93a | ||
|
|
59944c0e2f | ||
|
|
9de94bd65f | ||
|
|
ff46fb8f29 | ||
|
|
d9243def30 |
@@ -10,7 +10,8 @@ jobs:
|
|||||||
uses: PepperDash/workflow-templates/.github/workflows/essentialsplugins-getversion.yml@main
|
uses: PepperDash/workflow-templates/.github/workflows/essentialsplugins-getversion.yml@main
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
build-4Series:
|
build-4Series:
|
||||||
uses: PepperDash/workflow-templates/.github/workflows/essentialsplugins-4Series-builds.yml@main
|
# uses: PepperDash/workflow-templates/.github/workflows/essentialsplugins-4Series-builds.yml@main
|
||||||
|
uses: PepperDash/workflow-templates/.github/workflows/essentialsplugins-4Series-builds.yml@reorder-steps
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
needs: getVersion
|
needs: getVersion
|
||||||
if: needs.getVersion.outputs.newVersion == 'true'
|
if: needs.getVersion.outputs.newVersion == 'true'
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -396,3 +396,4 @@ _site/
|
|||||||
api/
|
api/
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
/._PepperDash.Essentials.4Series.sln
|
/._PepperDash.Essentials.4Series.sln
|
||||||
|
dotnet
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>2.15.1-local</Version>
|
<Version>2.19.4-local</Version>
|
||||||
<InformationalVersion>$(Version)</InformationalVersion>
|
<InformationalVersion>$(Version)</InformationalVersion>
|
||||||
<Authors>PepperDash Technology</Authors>
|
<Authors>PepperDash Technology</Authors>
|
||||||
<Company>PepperDash Technology</Company>
|
<Company>PepperDash Technology</Company>
|
||||||
|
|||||||
43
src/PepperDash.Core/ComTextHelper.cs
Normal file
43
src/PepperDash.Core/ComTextHelper.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace PepperDash.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Helper class for formatting communication text and byte data for debugging purposes.
|
||||||
|
/// </summary>
|
||||||
|
public class ComTextHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets escaped text for a byte array
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes"></param>
|
||||||
|
/// <returns>string with all bytes escaped</returns>
|
||||||
|
public static string GetEscapedText(byte[] bytes)
|
||||||
|
{
|
||||||
|
return string.Concat(bytes.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets escaped text for a string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <returns>string with all bytes escaped</returns>
|
||||||
|
public static string GetEscapedText(string text)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.GetEncoding(28591).GetBytes(text);
|
||||||
|
return string.Concat(bytes.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets debug text for a string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <returns>string with all non-printable characters escaped</returns>
|
||||||
|
public static string GetDebugText(string text)
|
||||||
|
{
|
||||||
|
return Regex.Replace(text, @"[^\u0020-\u007E]", a => GetEscapedText(a.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
@@ -37,14 +36,14 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _DebugTimeoutInMs/60000;
|
return _DebugTimeoutInMs / 60000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the RxStreamDebuggingIsEnabled
|
/// Gets or sets the RxStreamDebuggingIsEnabled
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool RxStreamDebuggingIsEnabled{ get; private set; }
|
public bool RxStreamDebuggingIsEnabled { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates that transmit stream debugging is enabled
|
/// Indicates that transmit stream debugging is enabled
|
||||||
@@ -136,51 +135,4 @@ namespace PepperDash.Core
|
|||||||
DebugExpiryPeriod = null;
|
DebugExpiryPeriod = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The available settings for stream debugging
|
|
||||||
/// </summary>
|
|
||||||
[Flags]
|
|
||||||
/// <summary>
|
|
||||||
/// Enumeration of eStreamDebuggingSetting values
|
|
||||||
/// </summary>
|
|
||||||
public enum eStreamDebuggingSetting
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Debug off
|
|
||||||
/// </summary>
|
|
||||||
Off = 0,
|
|
||||||
/// <summary>
|
|
||||||
/// Debug received data
|
|
||||||
/// </summary>
|
|
||||||
Rx = 1,
|
|
||||||
/// <summary>
|
|
||||||
/// Debug transmitted data
|
|
||||||
/// </summary>
|
|
||||||
Tx = 2,
|
|
||||||
/// <summary>
|
|
||||||
/// Debug both received and transmitted data
|
|
||||||
/// </summary>
|
|
||||||
Both = Rx | Tx
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The available settings for stream debugging response types
|
|
||||||
/// </summary>
|
|
||||||
[Flags]
|
|
||||||
public enum eStreamDebuggingDataTypeSettings
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Debug data in byte format
|
|
||||||
/// </summary>
|
|
||||||
Bytes = 0,
|
|
||||||
/// <summary>
|
|
||||||
/// Debug data in text format
|
|
||||||
/// </summary>
|
|
||||||
Text = 1,
|
|
||||||
/// <summary>
|
|
||||||
/// Debug data in both byte and text formats
|
|
||||||
/// </summary>
|
|
||||||
Both = Bytes | Text,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
@@ -11,11 +12,12 @@ using Renci.SshNet.Common;
|
|||||||
namespace PepperDash.Core
|
namespace PepperDash.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// SSH Client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericSshClient : Device, ISocketStatusWithStreamDebugging, IAutoReconnect
|
public class GenericSshClient : Device, ISocketStatusWithStreamDebugging, IAutoReconnect
|
||||||
{
|
{
|
||||||
private const string SPlusKey = "Uninitialized SshClient";
|
private const string SPlusKey = "Uninitialized SshClient";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Object to enable stream debugging
|
/// Object to enable stream debugging
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -36,11 +38,6 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange;
|
public event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/////
|
|
||||||
///// </summary>
|
|
||||||
//public event GenericSocketStatusChangeEventDelegate SocketStatusChange;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Hostname
|
/// Gets or sets the Hostname
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -67,7 +64,7 @@ namespace PepperDash.Core
|
|||||||
public bool IsConnected
|
public bool IsConnected
|
||||||
{
|
{
|
||||||
// returns false if no client or not connected
|
// returns false if no client or not connected
|
||||||
get { return Client != null && ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
|
get { return client != null && ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -83,16 +80,26 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public SocketStatus ClientStatus
|
public SocketStatus ClientStatus
|
||||||
{
|
{
|
||||||
get { return _ClientStatus; }
|
get { lock (_stateLock) { return _ClientStatus; } }
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
if (_ClientStatus == value)
|
bool shouldFireEvent = false;
|
||||||
return;
|
lock (_stateLock)
|
||||||
_ClientStatus = value;
|
{
|
||||||
OnConnectionChange();
|
if (_ClientStatus != value)
|
||||||
|
{
|
||||||
|
_ClientStatus = value;
|
||||||
|
shouldFireEvent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fire event outside lock to avoid deadlock
|
||||||
|
if (shouldFireEvent)
|
||||||
|
OnConnectionChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SocketStatus _ClientStatus;
|
|
||||||
|
private SocketStatus _ClientStatus;
|
||||||
|
private bool _ConnectEnabled;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains the familiar Simpl analog status values. This drives the ConnectionChange event
|
/// Contains the familiar Simpl analog status values. This drives the ConnectionChange event
|
||||||
@@ -100,7 +107,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ushort UStatus
|
public ushort UStatus
|
||||||
{
|
{
|
||||||
get { return (ushort)_ClientStatus; }
|
get { lock (_stateLock) { return (ushort)_ClientStatus; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -111,7 +118,11 @@ namespace PepperDash.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Will be set and unset by connect and disconnect only
|
/// Will be set and unset by connect and disconnect only
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ConnectEnabled { get; private set; }
|
public bool ConnectEnabled
|
||||||
|
{
|
||||||
|
get { lock (_stateLock) { return _ConnectEnabled; } }
|
||||||
|
private set { lock (_stateLock) { _ConnectEnabled = value; } }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// S+ helper for AutoReconnect
|
/// S+ helper for AutoReconnect
|
||||||
@@ -127,17 +138,25 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int AutoReconnectIntervalMs { get; set; }
|
public int AutoReconnectIntervalMs { get; set; }
|
||||||
|
|
||||||
SshClient Client;
|
private SshClient client;
|
||||||
|
|
||||||
ShellStream TheStream;
|
private ShellStream shellStream;
|
||||||
|
|
||||||
CTimer ReconnectTimer;
|
private readonly Timer reconnectTimer;
|
||||||
|
|
||||||
//Lock object to prevent simulatneous connect/disconnect operations
|
//Lock object to prevent simulatneous connect/disconnect operations
|
||||||
//private CCriticalSection connectLock = new CCriticalSection();
|
//private CCriticalSection connectLock = new CCriticalSection();
|
||||||
private SemaphoreSlim connectLock = new SemaphoreSlim(1);
|
private readonly SemaphoreSlim connectLock = new SemaphoreSlim(1);
|
||||||
|
|
||||||
private bool DisconnectLogged = false;
|
// Thread-safety lock for state changes
|
||||||
|
private readonly object _stateLock = new object();
|
||||||
|
|
||||||
|
private bool disconnectLogged = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When true, turns off echo for the SSH session
|
||||||
|
/// </summary>
|
||||||
|
public bool DisableEcho { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Typical constructor.
|
/// Typical constructor.
|
||||||
@@ -154,13 +173,13 @@ namespace PepperDash.Core
|
|||||||
Password = password;
|
Password = password;
|
||||||
AutoReconnectIntervalMs = 5000;
|
AutoReconnectIntervalMs = 5000;
|
||||||
|
|
||||||
ReconnectTimer = new CTimer(o =>
|
reconnectTimer = new Timer(o =>
|
||||||
{
|
{
|
||||||
if (ConnectEnabled)
|
if (ConnectEnabled) // Now thread-safe property access
|
||||||
{
|
{
|
||||||
Connect();
|
Connect();
|
||||||
}
|
}
|
||||||
}, System.Threading.Timeout.Infinite);
|
}, null, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -172,23 +191,23 @@ namespace PepperDash.Core
|
|||||||
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
||||||
AutoReconnectIntervalMs = 5000;
|
AutoReconnectIntervalMs = 5000;
|
||||||
|
|
||||||
ReconnectTimer = new CTimer(o =>
|
reconnectTimer = new Timer(o =>
|
||||||
{
|
{
|
||||||
if (ConnectEnabled)
|
if (ConnectEnabled) // Now thread-safe property access
|
||||||
{
|
{
|
||||||
Connect();
|
Connect();
|
||||||
}
|
}
|
||||||
}, System.Threading.Timeout.Infinite);
|
}, null, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles closing this up when the program shuts down
|
/// Handles closing this up when the program shuts down
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
|
private void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
|
||||||
{
|
{
|
||||||
if (programEventType == eProgramStatusEventType.Stopping)
|
if (programEventType == eProgramStatusEventType.Stopping)
|
||||||
{
|
{
|
||||||
if (Client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
this.LogDebug("Program stopping. Closing connection");
|
this.LogDebug("Program stopping. Closing connection");
|
||||||
Disconnect();
|
Disconnect();
|
||||||
@@ -223,10 +242,10 @@ namespace PepperDash.Core
|
|||||||
this.LogDebug("Attempting connect");
|
this.LogDebug("Attempting connect");
|
||||||
|
|
||||||
// Cancel reconnect if running.
|
// Cancel reconnect if running.
|
||||||
ReconnectTimer?.Stop();
|
StopReconnectTimer();
|
||||||
|
|
||||||
// Cleanup the old client if it already exists
|
// Cleanup the old client if it already exists
|
||||||
if (Client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
this.LogDebug("Cleaning up disconnected client");
|
this.LogDebug("Cleaning up disconnected client");
|
||||||
KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY);
|
KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY);
|
||||||
@@ -239,29 +258,36 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
this.LogDebug("Creating new SshClient");
|
this.LogDebug("Creating new SshClient");
|
||||||
ConnectionInfo connectionInfo = new ConnectionInfo(Hostname, Port, Username, pauth, kauth);
|
ConnectionInfo connectionInfo = new ConnectionInfo(Hostname, Port, Username, pauth, kauth);
|
||||||
Client = new SshClient(connectionInfo);
|
client = new SshClient(connectionInfo);
|
||||||
Client.ErrorOccurred += Client_ErrorOccurred;
|
client.ErrorOccurred += Client_ErrorOccurred;
|
||||||
|
|
||||||
//Attempt to connect
|
//Attempt to connect
|
||||||
ClientStatus = SocketStatus.SOCKET_STATUS_WAITING;
|
ClientStatus = SocketStatus.SOCKET_STATUS_WAITING;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Client.Connect();
|
client.Connect();
|
||||||
TheStream = Client.CreateShellStream("PDTShell", 0, 0, 0, 0, 65534);
|
|
||||||
if (TheStream.DataAvailable)
|
var modes = new Dictionary<TerminalModes, uint>();
|
||||||
|
|
||||||
|
if (DisableEcho)
|
||||||
|
{
|
||||||
|
modes.Add(TerminalModes.ECHO, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
shellStream = client.CreateShellStream("PDTShell", 0, 0, 0, 0, 65534, modes);
|
||||||
|
if (shellStream.DataAvailable)
|
||||||
{
|
{
|
||||||
// empty the buffer if there is data
|
// empty the buffer if there is data
|
||||||
string str = TheStream.Read();
|
shellStream.Read();
|
||||||
}
|
}
|
||||||
TheStream.DataReceived += Stream_DataReceived;
|
shellStream.DataReceived += Stream_DataReceived;
|
||||||
this.LogInformation("Connected");
|
this.LogInformation("Connected");
|
||||||
ClientStatus = SocketStatus.SOCKET_STATUS_CONNECTED;
|
ClientStatus = SocketStatus.SOCKET_STATUS_CONNECTED;
|
||||||
DisconnectLogged = false;
|
disconnectLogged = false;
|
||||||
}
|
}
|
||||||
catch (SshConnectionException e)
|
catch (SshConnectionException e)
|
||||||
{
|
{
|
||||||
var ie = e.InnerException; // The details are inside!!
|
var ie = e.InnerException; // The details are inside!!
|
||||||
var errorLogLevel = DisconnectLogged == true ? Debug.ErrorLogLevel.None : Debug.ErrorLogLevel.Error;
|
|
||||||
|
|
||||||
if (ie is SocketException)
|
if (ie is SocketException)
|
||||||
{
|
{
|
||||||
@@ -286,37 +312,36 @@ namespace PepperDash.Core
|
|||||||
this.LogVerbose(ie, "Exception details: ");
|
this.LogVerbose(ie, "Exception details: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
DisconnectLogged = true;
|
disconnectLogged = true;
|
||||||
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
|
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
|
||||||
if (AutoReconnect)
|
if (AutoReconnect)
|
||||||
{
|
{
|
||||||
this.LogDebug("Checking autoreconnect: {autoReconnect}, {autoReconnectInterval}ms", AutoReconnect, AutoReconnectIntervalMs);
|
this.LogDebug("Checking autoreconnect: {autoReconnect}, {autoReconnectInterval}ms", AutoReconnect, AutoReconnectIntervalMs);
|
||||||
ReconnectTimer.Reset(AutoReconnectIntervalMs);
|
StartReconnectTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SshOperationTimeoutException ex)
|
catch (SshOperationTimeoutException ex)
|
||||||
{
|
{
|
||||||
this.LogWarning("Connection attempt timed out: {message}", ex.Message);
|
this.LogWarning("Connection attempt timed out: {message}", ex.Message);
|
||||||
|
|
||||||
DisconnectLogged = true;
|
disconnectLogged = true;
|
||||||
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
|
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
|
||||||
if (AutoReconnect)
|
if (AutoReconnect)
|
||||||
{
|
{
|
||||||
this.LogDebug("Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs);
|
this.LogDebug("Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs);
|
||||||
ReconnectTimer.Reset(AutoReconnectIntervalMs);
|
StartReconnectTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
var errorLogLevel = DisconnectLogged == true ? Debug.ErrorLogLevel.None : Debug.ErrorLogLevel.Error;
|
|
||||||
this.LogError("Unhandled exception on connect: {error}", e.Message);
|
this.LogError("Unhandled exception on connect: {error}", e.Message);
|
||||||
this.LogVerbose(e, "Exception details: ");
|
this.LogVerbose(e, "Exception details: ");
|
||||||
DisconnectLogged = true;
|
disconnectLogged = true;
|
||||||
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
|
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
|
||||||
if (AutoReconnect)
|
if (AutoReconnect)
|
||||||
{
|
{
|
||||||
this.LogDebug("Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs);
|
this.LogDebug("Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs);
|
||||||
ReconnectTimer.Reset(AutoReconnectIntervalMs);
|
StartReconnectTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,11 +359,7 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
ConnectEnabled = false;
|
ConnectEnabled = false;
|
||||||
// Stop trying reconnects, if we are
|
// Stop trying reconnects, if we are
|
||||||
if (ReconnectTimer != null)
|
StopReconnectTimer();
|
||||||
{
|
|
||||||
ReconnectTimer.Stop();
|
|
||||||
// ReconnectTimer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY);
|
KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY);
|
||||||
}
|
}
|
||||||
@@ -352,12 +373,12 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (Client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
Client.ErrorOccurred -= Client_ErrorOccurred;
|
client.ErrorOccurred -= Client_ErrorOccurred;
|
||||||
Client.Disconnect();
|
client.Disconnect();
|
||||||
Client.Dispose();
|
client.Dispose();
|
||||||
Client = null;
|
client = null;
|
||||||
ClientStatus = status;
|
ClientStatus = status;
|
||||||
this.LogDebug("Disconnected");
|
this.LogDebug("Disconnected");
|
||||||
}
|
}
|
||||||
@@ -371,16 +392,16 @@ namespace PepperDash.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Kills the stream
|
/// Kills the stream
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void KillStream()
|
private void KillStream()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (TheStream != null)
|
if (shellStream != null)
|
||||||
{
|
{
|
||||||
TheStream.DataReceived -= Stream_DataReceived;
|
shellStream.DataReceived -= Stream_DataReceived;
|
||||||
TheStream.Close();
|
shellStream.Close();
|
||||||
TheStream.Dispose();
|
shellStream.Dispose();
|
||||||
TheStream = null;
|
shellStream = null;
|
||||||
this.LogDebug("Disconnected stream");
|
this.LogDebug("Disconnected stream");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -393,7 +414,7 @@ namespace PepperDash.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles the keyboard interactive authentication, should it be required.
|
/// Handles the keyboard interactive authentication, should it be required.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void kauth_AuthenticationPrompt(object sender, AuthenticationPromptEventArgs e)
|
private void kauth_AuthenticationPrompt(object sender, AuthenticationPromptEventArgs e)
|
||||||
{
|
{
|
||||||
foreach (AuthenticationPrompt prompt in e.Prompts)
|
foreach (AuthenticationPrompt prompt in e.Prompts)
|
||||||
if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1)
|
if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1)
|
||||||
@@ -403,7 +424,7 @@ namespace PepperDash.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handler for data receive on ShellStream. Passes data across to queue for line parsing.
|
/// Handler for data receive on ShellStream. Passes data across to queue for line parsing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Stream_DataReceived(object sender, ShellDataEventArgs e)
|
private void Stream_DataReceived(object sender, ShellDataEventArgs e)
|
||||||
{
|
{
|
||||||
if (((ShellStream)sender).Length <= 0L)
|
if (((ShellStream)sender).Length <= 0L)
|
||||||
{
|
{
|
||||||
@@ -416,18 +437,14 @@ namespace PepperDash.Core
|
|||||||
if (bytesHandler != null)
|
if (bytesHandler != null)
|
||||||
{
|
{
|
||||||
var bytes = Encoding.UTF8.GetBytes(response);
|
var bytes = Encoding.UTF8.GetBytes(response);
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
this.PrintReceivedBytes(bytes);
|
||||||
{
|
|
||||||
this.LogInformation("Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
|
|
||||||
}
|
|
||||||
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
var textHandler = TextReceived;
|
var textHandler = TextReceived;
|
||||||
if (textHandler != null)
|
if (textHandler != null)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
this.PrintReceivedText(response);
|
||||||
this.LogInformation("Received: '{0}'", ComTextHelper.GetDebugText(response));
|
|
||||||
|
|
||||||
textHandler(this, new GenericCommMethodReceiveTextArgs(response));
|
textHandler(this, new GenericCommMethodReceiveTextArgs(response));
|
||||||
}
|
}
|
||||||
@@ -439,7 +456,7 @@ namespace PepperDash.Core
|
|||||||
/// Error event handler for client events - disconnect, etc. Will forward those events via ConnectionChange
|
/// Error event handler for client events - disconnect, etc. Will forward those events via ConnectionChange
|
||||||
/// event
|
/// event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Client_ErrorOccurred(object sender, ExceptionEventArgs e)
|
private void Client_ErrorOccurred(object sender, ExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
CrestronInvoke.BeginInvoke(o =>
|
CrestronInvoke.BeginInvoke(o =>
|
||||||
{
|
{
|
||||||
@@ -459,7 +476,7 @@ namespace PepperDash.Core
|
|||||||
if (AutoReconnect && ConnectEnabled)
|
if (AutoReconnect && ConnectEnabled)
|
||||||
{
|
{
|
||||||
this.LogDebug("Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs);
|
this.LogDebug("Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs);
|
||||||
ReconnectTimer.Reset(AutoReconnectIntervalMs);
|
StartReconnectTimer();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -467,7 +484,7 @@ namespace PepperDash.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper for ConnectionChange event
|
/// Helper for ConnectionChange event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void OnConnectionChange()
|
private void OnConnectionChange()
|
||||||
{
|
{
|
||||||
ConnectionChange?.Invoke(this, new GenericSocketStatusChageEventArgs(this));
|
ConnectionChange?.Invoke(this, new GenericSocketStatusChageEventArgs(this));
|
||||||
}
|
}
|
||||||
@@ -482,16 +499,12 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (Client != null && TheStream != null && IsConnected)
|
if (client != null && shellStream != null && IsConnected)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
this.PrintSentText(text);
|
||||||
this.LogInformation(
|
|
||||||
"Sending {length} characters of text: '{text}'",
|
|
||||||
text.Length,
|
|
||||||
ComTextHelper.GetDebugText(text));
|
|
||||||
|
|
||||||
TheStream.Write(text);
|
shellStream.Write(text);
|
||||||
TheStream.Flush();
|
shellStream.Flush();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -503,7 +516,7 @@ namespace PepperDash.Core
|
|||||||
this.LogError("ObjectDisposedException sending '{message}'. Restarting connection...", text.Trim());
|
this.LogError("ObjectDisposedException sending '{message}'. Restarting connection...", text.Trim());
|
||||||
|
|
||||||
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
|
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
|
||||||
ReconnectTimer.Reset();
|
StartReconnectTimer();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -519,13 +532,12 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (Client != null && TheStream != null && IsConnected)
|
if (client != null && shellStream != null && IsConnected)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
this.PrintSentBytes(bytes);
|
||||||
this.LogInformation("Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
|
||||||
|
|
||||||
TheStream.Write(bytes, 0, bytes.Length);
|
shellStream.Write(bytes, 0, bytes.Length);
|
||||||
TheStream.Flush();
|
shellStream.Flush();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -537,7 +549,7 @@ namespace PepperDash.Core
|
|||||||
this.LogException(ex, "ObjectDisposedException sending {message}", ComTextHelper.GetEscapedText(bytes));
|
this.LogException(ex, "ObjectDisposedException sending {message}", ComTextHelper.GetEscapedText(bytes));
|
||||||
|
|
||||||
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
|
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
|
||||||
ReconnectTimer.Reset();
|
StartReconnectTimer();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -546,6 +558,83 @@ namespace PepperDash.Core
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Safely starts the reconnect timer with exception handling
|
||||||
|
/// </summary>
|
||||||
|
private void StartReconnectTimer()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reconnectTimer?.Change(AutoReconnectIntervalMs, System.Threading.Timeout.Infinite);
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
// Timer was disposed, ignore
|
||||||
|
this.LogDebug("Attempted to start timer but it was already disposed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Safely stops the reconnect timer with exception handling
|
||||||
|
/// </summary>
|
||||||
|
private void StopReconnectTimer()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reconnectTimer?.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
// Timer was disposed, ignore
|
||||||
|
this.LogDebug("Attempted to stop timer but it was already disposed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deactivate method - properly dispose of resources
|
||||||
|
/// </summary>
|
||||||
|
public override bool Deactivate()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.LogDebug("Deactivating SSH client - disposing resources");
|
||||||
|
|
||||||
|
// Stop trying reconnects
|
||||||
|
ConnectEnabled = false;
|
||||||
|
StopReconnectTimer();
|
||||||
|
|
||||||
|
// Disconnect and cleanup client
|
||||||
|
KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY);
|
||||||
|
|
||||||
|
// Dispose timer
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reconnectTimer?.Dispose();
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
// Already disposed, ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispose semaphore
|
||||||
|
try
|
||||||
|
{
|
||||||
|
connectLock?.Dispose();
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
// Already disposed, ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.Deactivate();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
this.LogException(ex, "Error during SSH client deactivation");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************************************************************************************
|
//*****************************************************************************************************
|
||||||
|
|||||||
@@ -19,44 +19,44 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public CommunicationStreamDebugging StreamDebugging { get; private set; }
|
public CommunicationStreamDebugging StreamDebugging { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fires when data is received from the server and returns it as a Byte array
|
/// Fires when data is received from the server and returns it as a Byte array
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fires when data is received from the server and returns it as text
|
/// Fires when data is received from the server and returns it as text
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
//public event GenericSocketStatusChangeEventDelegate SocketStatusChange;
|
//public event GenericSocketStatusChangeEventDelegate SocketStatusChange;
|
||||||
public event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange;
|
public event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange;
|
||||||
|
|
||||||
|
|
||||||
private string _hostname;
|
private string _hostname;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Address of server
|
/// Address of server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Hostname
|
public string Hostname
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _hostname;
|
return _hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_hostname = value;
|
_hostname = value;
|
||||||
if (_client != null)
|
if (_client != null)
|
||||||
{
|
{
|
||||||
_client.AddressClientConnectedTo = _hostname;
|
_client.AddressClientConnectedTo = _hostname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Port
|
/// Gets or sets the Port
|
||||||
@@ -78,15 +78,15 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int BufferSize { get; set; }
|
public int BufferSize { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The actual client class
|
/// The actual client class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private TCPClient _client;
|
private TCPClient _client;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Bool showing if socket is connected
|
/// Bool showing if socket is connected
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsConnected
|
public bool IsConnected
|
||||||
{
|
{
|
||||||
get { return _client != null && _client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
|
get { return _client != null && _client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
|
||||||
}
|
}
|
||||||
@@ -99,10 +99,10 @@ namespace PepperDash.Core
|
|||||||
get { return (ushort)(IsConnected ? 1 : 0); }
|
get { return (ushort)(IsConnected ? 1 : 0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// _client socket status Read only
|
/// _client socket status Read only
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SocketStatus ClientStatus
|
public SocketStatus ClientStatus
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -119,26 +119,26 @@ namespace PepperDash.Core
|
|||||||
get { return (ushort)ClientStatus; }
|
get { return (ushort)ClientStatus; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Status text shows the message associated with socket status
|
/// Status text shows the message associated with socket status
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ClientStatusText { get { return ClientStatus.ToString(); } }
|
public string ClientStatusText { get { return ClientStatus.ToString(); } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ushort representation of client status
|
/// Ushort representation of client status
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Obsolete]
|
[Obsolete]
|
||||||
public ushort UClientStatus { get { return (ushort)ClientStatus; } }
|
public ushort UClientStatus { get { return (ushort)ClientStatus; } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connection failure reason
|
/// Connection failure reason
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ConnectionFailure { get { return ClientStatus.ToString(); } }
|
public string ConnectionFailure { get { return ClientStatus.ToString(); } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the AutoReconnect
|
/// Gets or sets the AutoReconnect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool AutoReconnect { get; set; }
|
public bool AutoReconnect { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// S+ helper for AutoReconnect
|
/// S+ helper for AutoReconnect
|
||||||
@@ -149,29 +149,29 @@ namespace PepperDash.Core
|
|||||||
set { AutoReconnect = value == 1; }
|
set { AutoReconnect = value == 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Milliseconds to wait before attempting to reconnect. Defaults to 5000
|
/// Milliseconds to wait before attempting to reconnect. Defaults to 5000
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int AutoReconnectIntervalMs { get; set; }
|
public int AutoReconnectIntervalMs { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set only when the disconnect method is called
|
/// Set only when the disconnect method is called
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool DisconnectCalledByUser;
|
bool DisconnectCalledByUser;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Connected
|
public bool Connected
|
||||||
{
|
{
|
||||||
get { return _client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
|
get { return _client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//Lock object to prevent simulatneous connect/disconnect operations
|
//Lock object to prevent simulatneous connect/disconnect operations
|
||||||
private CCriticalSection connectLock = new CCriticalSection();
|
private CCriticalSection connectLock = new CCriticalSection();
|
||||||
|
|
||||||
// private Timer for auto reconnect
|
// private Timer for auto reconnect
|
||||||
private CTimer RetryTimer;
|
private CTimer RetryTimer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
@@ -181,8 +181,8 @@ namespace PepperDash.Core
|
|||||||
/// <param name="port"></param>
|
/// <param name="port"></param>
|
||||||
/// <param name="bufferSize"></param>
|
/// <param name="bufferSize"></param>
|
||||||
public GenericTcpIpClient(string key, string address, int port, int bufferSize)
|
public GenericTcpIpClient(string key, string address, int port, int bufferSize)
|
||||||
: base(key)
|
: base(key)
|
||||||
{
|
{
|
||||||
StreamDebugging = new CommunicationStreamDebugging(key);
|
StreamDebugging = new CommunicationStreamDebugging(key);
|
||||||
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
||||||
AutoReconnectIntervalMs = 5000;
|
AutoReconnectIntervalMs = 5000;
|
||||||
@@ -218,18 +218,18 @@ namespace PepperDash.Core
|
|||||||
/// Default constructor for S+
|
/// Default constructor for S+
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GenericTcpIpClient()
|
public GenericTcpIpClient()
|
||||||
: base(SplusKey)
|
: base(SplusKey)
|
||||||
{
|
{
|
||||||
StreamDebugging = new CommunicationStreamDebugging(SplusKey);
|
StreamDebugging = new CommunicationStreamDebugging(SplusKey);
|
||||||
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
||||||
AutoReconnectIntervalMs = 5000;
|
AutoReconnectIntervalMs = 5000;
|
||||||
BufferSize = 2000;
|
BufferSize = 2000;
|
||||||
|
|
||||||
RetryTimer = new CTimer(o =>
|
RetryTimer = new CTimer(o =>
|
||||||
{
|
{
|
||||||
Reconnect();
|
Reconnect();
|
||||||
}, Timeout.Infinite);
|
}, Timeout.Infinite);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize method
|
/// Initialize method
|
||||||
@@ -255,26 +255,26 @@ namespace PepperDash.Core
|
|||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deactivate method
|
/// Deactivate method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override bool Deactivate()
|
public override bool Deactivate()
|
||||||
{
|
{
|
||||||
RetryTimer.Stop();
|
RetryTimer.Stop();
|
||||||
RetryTimer.Dispose();
|
RetryTimer.Dispose();
|
||||||
if (_client != null)
|
if (_client != null)
|
||||||
{
|
{
|
||||||
_client.SocketStatusChange -= this.Client_SocketStatusChange;
|
_client.SocketStatusChange -= this.Client_SocketStatusChange;
|
||||||
DisconnectClient();
|
DisconnectClient();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connect method
|
/// Connect method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Connect()
|
public void Connect()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(Hostname))
|
if (string.IsNullOrEmpty(Hostname))
|
||||||
{
|
{
|
||||||
Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericTcpIpClient '{0}': No address set", Key);
|
Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericTcpIpClient '{0}': No address set", Key);
|
||||||
@@ -310,7 +310,7 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
connectLock.Leave();
|
connectLock.Leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Reconnect()
|
private void Reconnect()
|
||||||
{
|
{
|
||||||
@@ -337,11 +337,11 @@ namespace PepperDash.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disconnect method
|
/// Disconnect method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Disconnect()
|
public void Disconnect()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
connectLock.Enter();
|
connectLock.Enter();
|
||||||
@@ -355,7 +355,7 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
connectLock.Leave();
|
connectLock.Leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DisconnectClient method
|
/// DisconnectClient method
|
||||||
@@ -375,7 +375,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="c"></param>
|
/// <param name="c"></param>
|
||||||
void ConnectToServerCallback(TCPClient c)
|
void ConnectToServerCallback(TCPClient c)
|
||||||
{
|
{
|
||||||
if (c.ClientStatus != SocketStatus.SOCKET_STATUS_CONNECTED)
|
if (c.ClientStatus != SocketStatus.SOCKET_STATUS_CONNECTED)
|
||||||
{
|
{
|
||||||
Debug.Console(0, this, "Server connection result: {0}", c.ClientStatus);
|
Debug.Console(0, this, "Server connection result: {0}", c.ClientStatus);
|
||||||
@@ -385,13 +385,13 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
Debug.Console(1, this, "Server connection result: {0}", c.ClientStatus);
|
Debug.Console(1, this, "Server connection result: {0}", c.ClientStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disconnects, waits and attemtps to connect again
|
/// Disconnects, waits and attemtps to connect again
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void WaitAndTryReconnect()
|
void WaitAndTryReconnect()
|
||||||
{
|
{
|
||||||
CrestronInvoke.BeginInvoke(o =>
|
CrestronInvoke.BeginInvoke(o =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -409,7 +409,7 @@ namespace PepperDash.Core
|
|||||||
connectLock.Leave();
|
connectLock.Leave();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Recieves incoming data
|
/// Recieves incoming data
|
||||||
@@ -417,7 +417,7 @@ namespace PepperDash.Core
|
|||||||
/// <param name="client"></param>
|
/// <param name="client"></param>
|
||||||
/// <param name="numBytes"></param>
|
/// <param name="numBytes"></param>
|
||||||
void Receive(TCPClient client, int numBytes)
|
void Receive(TCPClient client, int numBytes)
|
||||||
{
|
{
|
||||||
if (client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
if (numBytes > 0)
|
if (numBytes > 0)
|
||||||
@@ -426,10 +426,7 @@ namespace PepperDash.Core
|
|||||||
var bytesHandler = BytesReceived;
|
var bytesHandler = BytesReceived;
|
||||||
if (bytesHandler != null)
|
if (bytesHandler != null)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
this.PrintReceivedBytes(bytes);
|
||||||
{
|
|
||||||
Debug.Console(0, this, "Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
|
|
||||||
}
|
|
||||||
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||||
}
|
}
|
||||||
var textHandler = TextReceived;
|
var textHandler = TextReceived;
|
||||||
@@ -437,58 +434,53 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
||||||
|
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
this.PrintReceivedText(str);
|
||||||
{
|
|
||||||
Debug.Console(0, this, "Received {1} characters of text: '{0}'", ComTextHelper.GetDebugText(str), str.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
textHandler(this, new GenericCommMethodReceiveTextArgs(str));
|
textHandler(this, new GenericCommMethodReceiveTextArgs(str));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
client.ReceiveDataAsync(Receive);
|
client.ReceiveDataAsync(Receive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SendText method
|
/// SendText method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendText(string text)
|
public void SendText(string text)
|
||||||
{
|
{
|
||||||
var bytes = Encoding.GetEncoding(28591).GetBytes(text);
|
var bytes = Encoding.GetEncoding(28591).GetBytes(text);
|
||||||
// Check debug level before processing byte array
|
// Check debug level before processing byte array
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
this.PrintSentText(text);
|
||||||
Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, ComTextHelper.GetDebugText(text));
|
|
||||||
if (_client != null)
|
if (_client != null)
|
||||||
_client.SendData(bytes, bytes.Length);
|
_client.SendData(bytes, bytes.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SendEscapedText method
|
/// SendEscapedText method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendEscapedText(string text)
|
public void SendEscapedText(string text)
|
||||||
{
|
{
|
||||||
var unescapedText = Regex.Replace(text, @"\\x([0-9a-fA-F][0-9a-fA-F])", s =>
|
var unescapedText = Regex.Replace(text, @"\\x([0-9a-fA-F][0-9a-fA-F])", s =>
|
||||||
{
|
{
|
||||||
var hex = s.Groups[1].Value;
|
var hex = s.Groups[1].Value;
|
||||||
return ((char)Convert.ToByte(hex, 16)).ToString();
|
return ((char)Convert.ToByte(hex, 16)).ToString();
|
||||||
});
|
});
|
||||||
SendText(unescapedText);
|
SendText(unescapedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends Bytes to the server
|
/// Sends Bytes to the server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes"></param>
|
/// <param name="bytes"></param>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SendBytes method
|
/// SendBytes method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendBytes(byte[] bytes)
|
public void SendBytes(byte[] bytes)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
this.PrintSentBytes(bytes);
|
||||||
Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
|
||||||
if (_client != null)
|
if (_client != null)
|
||||||
_client.SendData(bytes, bytes.Length);
|
_client.SendData(bytes, bytes.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Socket Status Change Handler
|
/// Socket Status Change Handler
|
||||||
@@ -496,7 +488,7 @@ namespace PepperDash.Core
|
|||||||
/// <param name="client"></param>
|
/// <param name="client"></param>
|
||||||
/// <param name="clientSocketStatus"></param>
|
/// <param name="clientSocketStatus"></param>
|
||||||
void Client_SocketStatusChange(TCPClient client, SocketStatus clientSocketStatus)
|
void Client_SocketStatusChange(TCPClient client, SocketStatus clientSocketStatus)
|
||||||
{
|
{
|
||||||
if (clientSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED)
|
if (clientSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED)
|
||||||
{
|
{
|
||||||
Debug.Console(0, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText);
|
Debug.Console(0, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText);
|
||||||
@@ -505,68 +497,73 @@ namespace PepperDash.Core
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText);
|
Debug.Console(1, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText);
|
||||||
_client.ReceiveDataAsync(Receive);
|
_client.ReceiveDataAsync(Receive);
|
||||||
}
|
}
|
||||||
|
|
||||||
var handler = ConnectionChange;
|
var handler = ConnectionChange;
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
ConnectionChange(this, new GenericSocketStatusChageEventArgs(this));
|
ConnectionChange(this, new GenericSocketStatusChageEventArgs(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a TcpSshPropertiesConfig
|
/// Represents a TcpSshPropertiesConfig
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TcpSshPropertiesConfig
|
public class TcpSshPropertiesConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Address to connect to
|
/// Address to connect to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty(Required = Required.Always)]
|
[JsonProperty(Required = Required.Always)]
|
||||||
public string Address { get; set; }
|
public string Address { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Port to connect to
|
/// Port to connect to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty(Required = Required.Always)]
|
[JsonProperty(Required = Required.Always)]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Username credential
|
/// Username credential
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Password
|
/// Gets or sets the Password
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defaults to 32768
|
/// Defaults to 32768
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int BufferSize { get; set; }
|
public int BufferSize { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the AutoReconnect
|
/// Gets or sets the AutoReconnect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool AutoReconnect { get; set; }
|
public bool AutoReconnect { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the AutoReconnectIntervalMs
|
/// Gets or sets the AutoReconnectIntervalMs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int AutoReconnectIntervalMs { get; set; }
|
public int AutoReconnectIntervalMs { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When true, turns off echo for the SSH session
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("disableSshEcho")]
|
||||||
|
public bool DisableSshEcho { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default constructor
|
/// Default constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TcpSshPropertiesConfig()
|
public TcpSshPropertiesConfig()
|
||||||
{
|
{
|
||||||
BufferSize = 32768;
|
BufferSize = 32768;
|
||||||
AutoReconnect = true;
|
AutoReconnect = true;
|
||||||
AutoReconnectIntervalMs = 5000;
|
AutoReconnectIntervalMs = 5000;
|
||||||
Username = "";
|
Username = "";
|
||||||
Password = "";
|
Password = "";
|
||||||
}
|
DisableSshEcho = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,14 +131,14 @@ namespace PepperDash.Core
|
|||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <param name="address"></param>
|
/// <param name="address"></param>
|
||||||
/// <param name="port"></param>
|
/// <param name="port"></param>
|
||||||
/// <param name="buffefSize"></param>
|
/// <param name="bufferSize"></param>
|
||||||
public GenericUdpServer(string key, string address, int port, int buffefSize)
|
public GenericUdpServer(string key, string address, int port, int bufferSize)
|
||||||
: base(key)
|
: base(key)
|
||||||
{
|
{
|
||||||
StreamDebugging = new CommunicationStreamDebugging(key);
|
StreamDebugging = new CommunicationStreamDebugging(key);
|
||||||
Hostname = address;
|
Hostname = address;
|
||||||
Port = port;
|
Port = port;
|
||||||
BufferSize = buffefSize;
|
BufferSize = bufferSize;
|
||||||
|
|
||||||
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
||||||
CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
|
CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
|
||||||
@@ -194,7 +194,21 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
if (Server == null)
|
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))
|
if (string.IsNullOrEmpty(Hostname))
|
||||||
@@ -229,7 +243,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Disconnect()
|
public void Disconnect()
|
||||||
{
|
{
|
||||||
if(Server != null)
|
if (Server != null)
|
||||||
Server.DisableUDPServer();
|
Server.DisableUDPServer();
|
||||||
|
|
||||||
IsConnected = false;
|
IsConnected = false;
|
||||||
@@ -267,17 +281,13 @@ namespace PepperDash.Core
|
|||||||
var bytesHandler = BytesReceived;
|
var bytesHandler = BytesReceived;
|
||||||
if (bytesHandler != null)
|
if (bytesHandler != null)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
this.PrintReceivedBytes(bytes);
|
||||||
{
|
|
||||||
Debug.Console(0, this, "Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
|
|
||||||
}
|
|
||||||
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||||
}
|
}
|
||||||
var textHandler = TextReceived;
|
var textHandler = TextReceived;
|
||||||
if (textHandler != null)
|
if (textHandler != null)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
this.PrintReceivedText(str);
|
||||||
Debug.Console(0, this, "Received {1} characters of text: '{0}'", ComTextHelper.GetDebugText(str), str.Length);
|
|
||||||
textHandler(this, new GenericCommMethodReceiveTextArgs(str));
|
textHandler(this, new GenericCommMethodReceiveTextArgs(str));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,8 +314,7 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
if (IsConnected && Server != null)
|
if (IsConnected && Server != null)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
this.PrintSentText(text);
|
||||||
Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, ComTextHelper.GetDebugText(text));
|
|
||||||
|
|
||||||
Server.SendData(bytes, bytes.Length);
|
Server.SendData(bytes, bytes.Length);
|
||||||
}
|
}
|
||||||
@@ -320,8 +329,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendBytes(byte[] bytes)
|
public void SendBytes(byte[] bytes)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
this.PrintSentBytes(bytes);
|
||||||
Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
|
||||||
|
|
||||||
if (IsConnected && Server != null)
|
if (IsConnected && Server != null)
|
||||||
Server.SendData(bytes, bytes.Length);
|
Server.SendData(bytes, bytes.Length);
|
||||||
@@ -329,11 +337,11 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a GenericUdpReceiveTextExtraArgs
|
/// Represents a GenericUdpReceiveTextExtraArgs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericUdpReceiveTextExtraArgs : EventArgs
|
public class GenericUdpReceiveTextExtraArgs : EventArgs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -345,7 +353,7 @@ namespace PepperDash.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Port { get; private set; }
|
public int Port { get; private set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -359,18 +367,18 @@ namespace PepperDash.Core
|
|||||||
/// <param name="port"></param>
|
/// <param name="port"></param>
|
||||||
/// <param name="bytes"></param>
|
/// <param name="bytes"></param>
|
||||||
public GenericUdpReceiveTextExtraArgs(string text, string ipAddress, int port, byte[] bytes)
|
public GenericUdpReceiveTextExtraArgs(string text, string ipAddress, int port, byte[] bytes)
|
||||||
{
|
{
|
||||||
Text = text;
|
Text = text;
|
||||||
IpAddress = ipAddress;
|
IpAddress = ipAddress;
|
||||||
Port = port;
|
Port = port;
|
||||||
Bytes = bytes;
|
Bytes = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stupid S+ Constructor
|
/// Stupid S+ Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GenericUdpReceiveTextExtraArgs() { }
|
public GenericUdpReceiveTextExtraArgs() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
|||||||
69
src/PepperDash.Core/Comm/StreamDebuggingExtensions.cs
Normal file
69
src/PepperDash.Core/Comm/StreamDebuggingExtensions.cs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods for stream debugging
|
||||||
|
/// </summary>
|
||||||
|
public static class StreamDebuggingExtensions
|
||||||
|
{
|
||||||
|
private static readonly string app = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? $"App {InitialParametersClass.ApplicationNumber}" : $"{InitialParametersClass.RoomId}";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Print the sent bytes to the console
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="comms">comms device</param>
|
||||||
|
/// <param name="bytes">bytes to print</param>
|
||||||
|
public static void PrintSentBytes(this IStreamDebugging comms, byte[] bytes)
|
||||||
|
{
|
||||||
|
if (!comms.StreamDebugging.TxStreamDebuggingIsEnabled) return;
|
||||||
|
|
||||||
|
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||||
|
|
||||||
|
CrestronConsole.PrintLine($"[{timestamp}][{app}][{comms.Key}] Sending {bytes.Length} bytes: '{ComTextHelper.GetEscapedText(bytes)}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Print the received bytes to the console
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="comms">comms device</param>
|
||||||
|
/// <param name="bytes">bytes to print</param>
|
||||||
|
public static void PrintReceivedBytes(this IStreamDebugging comms, byte[] bytes)
|
||||||
|
{
|
||||||
|
if (!comms.StreamDebugging.RxStreamDebuggingIsEnabled) return;
|
||||||
|
|
||||||
|
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||||
|
|
||||||
|
CrestronConsole.PrintLine($"[{timestamp}][{app}][{comms.Key}] Received {bytes.Length} bytes: '{ComTextHelper.GetEscapedText(bytes)}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Print the sent text to the console
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="comms">comms device</param>
|
||||||
|
/// <param name="text">text to print</param>
|
||||||
|
public static void PrintSentText(this IStreamDebugging comms, string text)
|
||||||
|
{
|
||||||
|
if (!comms.StreamDebugging.TxStreamDebuggingIsEnabled) return;
|
||||||
|
|
||||||
|
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||||
|
|
||||||
|
CrestronConsole.PrintLine($"[{timestamp}][{app}][{comms.Key}] Sending Text: '{ComTextHelper.GetDebugText(text)}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Print the received text to the console
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="comms">comms device</param>
|
||||||
|
/// <param name="text">text to print</param>
|
||||||
|
public static void PrintReceivedText(this IStreamDebugging comms, string text)
|
||||||
|
{
|
||||||
|
if (!comms.StreamDebugging.RxStreamDebuggingIsEnabled) return;
|
||||||
|
|
||||||
|
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||||
|
|
||||||
|
CrestronConsole.PrintLine($"[{timestamp}][{app}][{comms.Key}] Received Text: '{ComTextHelper.GetDebugText(text)}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -78,6 +78,10 @@ namespace PepperDash.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used when comms needs to be handled in SIMPL and bridged opposite the normal direction
|
/// Used when comms needs to be handled in SIMPL and bridged opposite the normal direction
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ComBridge
|
ComBridge,
|
||||||
|
/// <summary>
|
||||||
|
/// InfinetEX control
|
||||||
|
/// </summary>
|
||||||
|
InfinetEx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
24
src/PepperDash.Core/Comm/eStreamDebuggingDataTypeSettings.cs
Normal file
24
src/PepperDash.Core/Comm/eStreamDebuggingDataTypeSettings.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PepperDash.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The available settings for stream debugging data format types
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
public enum eStreamDebuggingDataTypeSettings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Debug data in byte format
|
||||||
|
/// </summary>
|
||||||
|
Bytes = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Debug data in text format
|
||||||
|
/// </summary>
|
||||||
|
Text = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// Debug data in both byte and text formats
|
||||||
|
/// </summary>
|
||||||
|
Both = Bytes | Text
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/PepperDash.Core/Comm/eStreamDebuggingSetting.cs
Normal file
28
src/PepperDash.Core/Comm/eStreamDebuggingSetting.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PepperDash.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The available settings for stream debugging
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
public enum eStreamDebuggingSetting
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Debug off
|
||||||
|
/// </summary>
|
||||||
|
Off = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Debug received data
|
||||||
|
/// </summary>
|
||||||
|
Rx = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// Debug transmitted data
|
||||||
|
/// </summary>
|
||||||
|
Tx = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// Debug both received and transmitted data
|
||||||
|
/// </summary>
|
||||||
|
Both = Rx | Tx
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
using Crestron.SimplSharp.CrestronSockets;
|
using Crestron.SimplSharp.CrestronSockets;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace PepperDash.Core
|
namespace PepperDash.Core
|
||||||
@@ -42,7 +39,7 @@ namespace PepperDash.Core
|
|||||||
/// Defines the contract for IBasicCommunication
|
/// Defines the contract for IBasicCommunication
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBasicCommunication : ICommunicationReceiver
|
public interface IBasicCommunication : ICommunicationReceiver
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send text to the device
|
/// Send text to the device
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -54,7 +51,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes"></param>
|
/// <param name="bytes"></param>
|
||||||
void SendBytes(byte[] bytes);
|
void SendBytes(byte[] bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a device that implements IBasicCommunication and IStreamDebugging
|
/// Represents a device that implements IBasicCommunication and IStreamDebugging
|
||||||
@@ -67,7 +64,7 @@ namespace PepperDash.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a device with stream debugging capablities
|
/// Represents a device with stream debugging capablities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IStreamDebugging
|
public interface IStreamDebugging : IKeyed
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Object to enable stream debugging
|
/// Object to enable stream debugging
|
||||||
@@ -76,12 +73,12 @@ namespace PepperDash.Core
|
|||||||
CommunicationStreamDebugging StreamDebugging { get; }
|
CommunicationStreamDebugging StreamDebugging { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For IBasicCommunication classes that have SocketStatus. GenericSshClient,
|
/// For IBasicCommunication classes that have SocketStatus. GenericSshClient,
|
||||||
/// GenericTcpIpClient
|
/// GenericTcpIpClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISocketStatus : IBasicCommunication
|
public interface ISocketStatus : IBasicCommunication
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Notifies of socket status changes
|
/// Notifies of socket status changes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -93,7 +90,7 @@ namespace PepperDash.Core
|
|||||||
[JsonProperty("clientStatus")]
|
[JsonProperty("clientStatus")]
|
||||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||||
SocketStatus ClientStatus { get; }
|
SocketStatus ClientStatus { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes a device that implements ISocketStatus and IStreamDebugging
|
/// Describes a device that implements ISocketStatus and IStreamDebugging
|
||||||
@@ -107,24 +104,24 @@ namespace PepperDash.Core
|
|||||||
/// Describes a device that can automatically attempt to reconnect
|
/// Describes a device that can automatically attempt to reconnect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IAutoReconnect
|
public interface IAutoReconnect
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enable automatic recconnect
|
/// Enable automatic recconnect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("autoReconnect")]
|
[JsonProperty("autoReconnect")]
|
||||||
bool AutoReconnect { get; set; }
|
bool AutoReconnect { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interval in ms to attempt automatic recconnections
|
/// Interval in ms to attempt automatic recconnections
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("autoReconnectIntervalMs")]
|
[JsonProperty("autoReconnectIntervalMs")]
|
||||||
int AutoReconnectIntervalMs { get; set; }
|
int AutoReconnectIntervalMs { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum eGenericCommMethodStatusChangeType
|
public enum eGenericCommMethodStatusChangeType
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connected
|
/// Connected
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -133,45 +130,45 @@ namespace PepperDash.Core
|
|||||||
/// Disconnected
|
/// Disconnected
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Disconnected
|
Disconnected
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This delegate defines handler for IBasicCommunication status changes
|
/// This delegate defines handler for IBasicCommunication status changes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="comm">Device firing the status change</param>
|
/// <param name="comm">Device firing the status change</param>
|
||||||
/// <param name="status"></param>
|
/// <param name="status"></param>
|
||||||
public delegate void GenericCommMethodStatusHandler(IBasicCommunication comm, eGenericCommMethodStatusChangeType status);
|
public delegate void GenericCommMethodStatusHandler(IBasicCommunication comm, eGenericCommMethodStatusChangeType status);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericCommMethodReceiveBytesArgs : EventArgs
|
public class GenericCommMethodReceiveBytesArgs : EventArgs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Bytes
|
/// Gets or sets the Bytes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte[] Bytes { get; private set; }
|
public byte[] Bytes { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes"></param>
|
/// <param name="bytes"></param>
|
||||||
public GenericCommMethodReceiveBytesArgs(byte[] bytes)
|
public GenericCommMethodReceiveBytesArgs(byte[] bytes)
|
||||||
{
|
{
|
||||||
Bytes = bytes;
|
Bytes = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// S+ Constructor
|
/// S+ Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GenericCommMethodReceiveBytesArgs() { }
|
public GenericCommMethodReceiveBytesArgs() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericCommMethodReceiveTextArgs : EventArgs
|
public class GenericCommMethodReceiveTextArgs : EventArgs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -185,9 +182,9 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text"></param>
|
/// <param name="text"></param>
|
||||||
public GenericCommMethodReceiveTextArgs(string text)
|
public GenericCommMethodReceiveTextArgs(string text)
|
||||||
{
|
{
|
||||||
Text = text;
|
Text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
@@ -195,59 +192,14 @@ namespace PepperDash.Core
|
|||||||
/// <param name="text"></param>
|
/// <param name="text"></param>
|
||||||
/// <param name="delimiter"></param>
|
/// <param name="delimiter"></param>
|
||||||
public GenericCommMethodReceiveTextArgs(string text, string delimiter)
|
public GenericCommMethodReceiveTextArgs(string text, string delimiter)
|
||||||
:this(text)
|
: this(text)
|
||||||
{
|
{
|
||||||
Delimiter = delimiter;
|
Delimiter = delimiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// S+ Constructor
|
|
||||||
/// </summary>
|
|
||||||
public GenericCommMethodReceiveTextArgs() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public class ComTextHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets escaped text for a byte array
|
/// S+ Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes"></param>
|
public GenericCommMethodReceiveTextArgs() { }
|
||||||
/// <returns></returns>
|
}
|
||||||
public static string GetEscapedText(byte[] bytes)
|
|
||||||
{
|
|
||||||
return String.Concat(bytes.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets escaped text for a string
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <summary>
|
|
||||||
/// GetEscapedText method
|
|
||||||
/// </summary>
|
|
||||||
public static string GetEscapedText(string text)
|
|
||||||
{
|
|
||||||
var bytes = Encoding.GetEncoding(28591).GetBytes(text);
|
|
||||||
return String.Concat(bytes.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets debug text for a string
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <summary>
|
|
||||||
/// GetDebugText method
|
|
||||||
/// </summary>
|
|
||||||
public static string GetDebugText(string text)
|
|
||||||
{
|
|
||||||
return Regex.Replace(text, @"[^\u0020-\u007E]", a => GetEscapedText(a.Value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -9,40 +9,59 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Core.Config
|
namespace PepperDash.Core.Config
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a Portal formatted config file
|
/// Reads a Portal formatted config file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PortalConfigReader
|
public class PortalConfigReader
|
||||||
{
|
{
|
||||||
/// <summary>
|
const string template = "template";
|
||||||
/// Reads the config file, checks if it needs a merge, merges and saves, then returns the merged Object.
|
const string system = "system";
|
||||||
/// </summary>
|
const string systemUrl = "system_url";
|
||||||
/// <returns>JObject of config file</returns>
|
const string templateUrl = "template_url";
|
||||||
public static void ReadAndMergeFileIfNecessary(string filePath, string savePath)
|
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
|
try
|
||||||
{
|
{
|
||||||
if (!File.Exists(filePath))
|
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);
|
"ERROR: Configuration file not present. Please load file to {0} and reset program", filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (StreamReader fs = new StreamReader(filePath))
|
using (StreamReader fs = new StreamReader(filePath))
|
||||||
{
|
{
|
||||||
var jsonObj = JObject.Parse(fs.ReadToEnd());
|
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.
|
// it's a double-config, merge it.
|
||||||
var merged = MergeConfigs(jsonObj);
|
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;
|
jsonObj = merged;
|
||||||
@@ -77,62 +96,62 @@ namespace PepperDash.Core.Config
|
|||||||
var merged = new JObject();
|
var merged = new JObject();
|
||||||
|
|
||||||
// Put together top-level objects
|
// Put together top-level objects
|
||||||
if (system["info"] != null)
|
if (system[info] != null)
|
||||||
merged.Add("info", Merge(template["info"], system["info"], "infO"));
|
merged.Add(info, Merge(template[info], system[info], info));
|
||||||
else
|
else
|
||||||
merged.Add("info", template["info"]);
|
merged.Add(info, template[info]);
|
||||||
|
|
||||||
merged.Add("devices", MergeArraysOnTopLevelProperty(template["devices"] as JArray,
|
merged.Add(devices, MergeArraysOnTopLevelProperty(template[devices] as JArray,
|
||||||
system["devices"] as JArray, "key", "devices"));
|
system[devices] as JArray, "key", devices));
|
||||||
|
|
||||||
if (system["rooms"] == null)
|
if (system[rooms] == null)
|
||||||
merged.Add("rooms", template["rooms"]);
|
merged.Add(rooms, template[rooms]);
|
||||||
else
|
else
|
||||||
merged.Add("rooms", MergeArraysOnTopLevelProperty(template["rooms"] as JArray,
|
merged.Add(rooms, MergeArraysOnTopLevelProperty(template[rooms] as JArray,
|
||||||
system["rooms"] as JArray, "key", "rooms"));
|
system[rooms] as JArray, "key", rooms));
|
||||||
|
|
||||||
if (system["sourceLists"] == null)
|
if (system[sourceLists] == null)
|
||||||
merged.Add("sourceLists", template["sourceLists"]);
|
merged.Add(sourceLists, template[sourceLists]);
|
||||||
else
|
else
|
||||||
merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"], "sourceLists"));
|
merged.Add(sourceLists, Merge(template[sourceLists], system[sourceLists], sourceLists));
|
||||||
|
|
||||||
if (system["destinationLists"] == null)
|
if (system[destinationLists] == null)
|
||||||
merged.Add("destinationLists", template["destinationLists"]);
|
merged.Add(destinationLists, template[destinationLists]);
|
||||||
else
|
else
|
||||||
merged.Add("destinationLists",
|
merged.Add(destinationLists,
|
||||||
Merge(template["destinationLists"], system["destinationLists"], "destinationLists"));
|
Merge(template[destinationLists], system[destinationLists], destinationLists));
|
||||||
|
|
||||||
|
|
||||||
if (system["cameraLists"] == null)
|
if (system[cameraLists] == null)
|
||||||
merged.Add("cameraLists", template["cameraLists"]);
|
merged.Add(cameraLists, template[cameraLists]);
|
||||||
else
|
else
|
||||||
merged.Add("cameraLists", Merge(template["cameraLists"], system["cameraLists"], "cameraLists"));
|
merged.Add(cameraLists, Merge(template[cameraLists], system[cameraLists], cameraLists));
|
||||||
|
|
||||||
if (system["audioControlPointLists"] == null)
|
if (system[audioControlPointLists] == null)
|
||||||
merged.Add("audioControlPointLists", template["audioControlPointLists"]);
|
merged.Add(audioControlPointLists, template[audioControlPointLists]);
|
||||||
else
|
else
|
||||||
merged.Add("audioControlPointLists",
|
merged.Add(audioControlPointLists,
|
||||||
Merge(template["audioControlPointLists"], system["audioControlPointLists"], "audioControlPointLists"));
|
Merge(template[audioControlPointLists], system[audioControlPointLists], audioControlPointLists));
|
||||||
|
|
||||||
|
|
||||||
// Template tie lines take precedence. Config tool doesn't do them at system
|
// Template tie lines take precedence. Config tool doesn't do them at system
|
||||||
// level anyway...
|
// level anyway...
|
||||||
if (template["tieLines"] != null)
|
if (template[tieLines] != null)
|
||||||
merged.Add("tieLines", template["tieLines"]);
|
merged.Add(tieLines, template[tieLines]);
|
||||||
else if (system["tieLines"] != null)
|
else if (system[tieLines] != null)
|
||||||
merged.Add("tieLines", system["tieLines"]);
|
merged.Add(tieLines, system[tieLines]);
|
||||||
else
|
else
|
||||||
merged.Add("tieLines", new JArray());
|
merged.Add(tieLines, new JArray());
|
||||||
|
|
||||||
if (template["joinMaps"] != null)
|
if (template[joinMaps] != null)
|
||||||
merged.Add("joinMaps", template["joinMaps"]);
|
merged.Add(joinMaps, template[joinMaps]);
|
||||||
else
|
else
|
||||||
merged.Add("joinMaps", new JObject());
|
merged.Add(joinMaps, new JObject());
|
||||||
|
|
||||||
if (system["global"] != null)
|
if (system[global] != null)
|
||||||
merged.Add("global", Merge(template["global"], system["global"], "global"));
|
merged.Add(global, Merge(template[global], system[global], global));
|
||||||
else
|
else
|
||||||
merged.Add("global", template["global"]);
|
merged.Add(global, template[global]);
|
||||||
|
|
||||||
//Debug.Console(2, "MERGED CONFIG RESULT: \x0d\x0a{0}", merged);
|
//Debug.Console(2, "MERGED CONFIG RESULT: \x0d\x0a{0}", merged);
|
||||||
return merged;
|
return merged;
|
||||||
@@ -228,7 +247,7 @@ namespace PepperDash.Core.Config
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
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 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 _errorLogLevelSwitch;
|
||||||
|
|
||||||
private static readonly LoggingLevelSwitch _fileLevelSwitch;
|
private static readonly LoggingLevelSwitch _fileLogLevelSwitch;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the minimum log level for the websocket sink.
|
/// Gets the minimum log level for the websocket sink.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LogEventLevel WebsocketMinimumLogLevel
|
public static LogEventLevel WebsocketMinimumLogLevel
|
||||||
{
|
{
|
||||||
get { return _websocketLoggingLevelSwitch.MinimumLevel; }
|
get { return _websocketLogLevelSwitch.MinimumLevel; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly DebugWebsocketSink _websocketSink;
|
private static readonly DebugWebsocketSink _websocketSink;
|
||||||
@@ -138,13 +138,13 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
var defaultFileLogLevel = GetStoredLogEventLevel(FileLevelStoreKey);
|
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);
|
_errorLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultErrorLogLevel);
|
||||||
|
|
||||||
_fileLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultFileLogLevel);
|
_fileLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultFileLogLevel);
|
||||||
|
|
||||||
_websocketSink = new DebugWebsocketSink(new JsonFormatter(renderMessage: true));
|
_websocketSink = new DebugWebsocketSink(new JsonFormatter(renderMessage: true));
|
||||||
|
|
||||||
@@ -162,14 +162,14 @@ namespace PepperDash.Core
|
|||||||
.MinimumLevel.Verbose()
|
.MinimumLevel.Verbose()
|
||||||
.Enrich.FromLogContext()
|
.Enrich.FromLogContext()
|
||||||
.Enrich.With(new CrestronEnricher())
|
.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(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: _websocketLoggingLevelSwitch)
|
.WriteTo.Sink(_websocketSink, levelSwitch: _websocketLogLevelSwitch)
|
||||||
.WriteTo.Sink(new DebugErrorLogSink(new ExpressionTemplate(errorLogTemplate)), levelSwitch: _errorLogLevelSwitch)
|
.WriteTo.Sink(new DebugErrorLogSink(new ExpressionTemplate(errorLogTemplate)), levelSwitch: _errorLogLevelSwitch)
|
||||||
.WriteTo.File(new RenderedCompactJsonFormatter(), logFilePath,
|
.WriteTo.File(new RenderedCompactJsonFormatter(), logFilePath,
|
||||||
rollingInterval: RollingInterval.Day,
|
rollingInterval: RollingInterval.Day,
|
||||||
restrictedToMinimumLevel: LogEventLevel.Debug,
|
restrictedToMinimumLevel: LogEventLevel.Debug,
|
||||||
retainedFileCountLimit: CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? 30 : 60,
|
retainedFileCountLimit: CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? 7 : 14,
|
||||||
levelSwitch: _fileLevelSwitch
|
levelSwitch: _fileLogLevelSwitch
|
||||||
);
|
);
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -237,10 +237,13 @@ namespace PepperDash.Core
|
|||||||
if (DoNotLoadConfigOnNextBoot)
|
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));
|
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>
|
/// <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");
|
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)
|
if (logLevel < 0 || logLevel > 5)
|
||||||
@@ -284,6 +287,8 @@ namespace PepperDash.Core
|
|||||||
return LogEventLevel.Information;
|
return LogEventLevel.Information;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CrestronConsole.PrintLine($"Stored log level for {levelStoreKey} is {logLevel}");
|
||||||
|
|
||||||
return (LogEventLevel)logLevel;
|
return (LogEventLevel)logLevel;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -349,7 +354,11 @@ namespace PepperDash.Core
|
|||||||
if (levelString.Trim() == "?")
|
if (levelString.Trim() == "?")
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse(
|
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[0]} = 0\r\n" +
|
||||||
$"{_logLevels[1]} = 1\r\n" +
|
$"{_logLevels[1]} = 1\r\n" +
|
||||||
$"{_logLevels[2]} = 2\r\n" +
|
$"{_logLevels[2]} = 2\r\n" +
|
||||||
@@ -361,32 +370,88 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(levelString.Trim()))
|
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;
|
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)
|
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;
|
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;
|
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
|
catch
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [0-5]");
|
CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [sink] [level]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,10 +481,10 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetDebugLevel(LogEventLevel level)
|
public static void SetDebugLevel(LogEventLevel level)
|
||||||
{
|
{
|
||||||
_consoleLoggingLevelSwitch.MinimumLevel = level;
|
_consoleLogLevelSwitch.MinimumLevel = level;
|
||||||
|
|
||||||
CrestronConsole.ConsoleCommandResponse("[Application {0}], Debug level set to {1}\r\n",
|
CrestronConsole.ConsoleCommandResponse("[Application {0}] Debug level set to {1}\r\n",
|
||||||
InitialParametersClass.ApplicationNumber, _consoleLoggingLevelSwitch.MinimumLevel);
|
InitialParametersClass.ApplicationNumber, _consoleLogLevelSwitch.MinimumLevel);
|
||||||
|
|
||||||
CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}");
|
CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}");
|
||||||
|
|
||||||
@@ -436,14 +501,14 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetWebSocketMinimumDebugLevel(LogEventLevel level)
|
public static void SetWebSocketMinimumDebugLevel(LogEventLevel level)
|
||||||
{
|
{
|
||||||
_websocketLoggingLevelSwitch.MinimumLevel = level;
|
_websocketLogLevelSwitch.MinimumLevel = level;
|
||||||
|
|
||||||
var err = CrestronDataStoreStatic.SetLocalUintValue(WebSocketLevelStoreKey, (uint)level);
|
var err = CrestronDataStoreStatic.SetLocalUintValue(WebSocketLevelStoreKey, (uint)level);
|
||||||
|
|
||||||
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||||
LogMessage(LogEventLevel.Information, "Error saving websocket debug level setting: {erro}", err);
|
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>
|
/// <summary>
|
||||||
@@ -453,12 +518,17 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
_errorLogLevelSwitch.MinimumLevel = level;
|
_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)
|
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||||
LogMessage(LogEventLevel.Information, "Error saving Error Log debug level setting: {error}", err);
|
CrestronConsole.PrintLine($"Error saving error log debug level setting: {err}");
|
||||||
|
|
||||||
LogMessage(LogEventLevel.Information, "Error log debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -466,14 +536,19 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetFileMinimumDebugLevel(LogEventLevel level)
|
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)
|
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||||
LogMessage(LogEventLevel.Information, "Error saving File debug level setting: {error}", err);
|
CrestronConsole.PrintLine($"Error saving file debug level setting: {err}");
|
||||||
|
|
||||||
LogMessage(LogEventLevel.Information, "File debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1006,9 +1081,6 @@ namespace PepperDash.Core
|
|||||||
/// Logs to Console when at-level, and all messages to error log
|
/// Logs to Console when at-level, and all messages to error log
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
|
[Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
|
||||||
/// <summary>
|
|
||||||
/// Console method
|
|
||||||
/// </summary>
|
|
||||||
public static void Console(uint level, ErrorLogLevel errorLogLevel,
|
public static void Console(uint level, ErrorLogLevel errorLogLevel,
|
||||||
string format, params object[] items)
|
string format, params object[] items)
|
||||||
{
|
{
|
||||||
@@ -1021,9 +1093,6 @@ namespace PepperDash.Core
|
|||||||
/// it will only be written to the log.
|
/// it will only be written to the log.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
|
[Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
|
||||||
/// <summary>
|
|
||||||
/// ConsoleWithLog method
|
|
||||||
/// </summary>
|
|
||||||
public static void ConsoleWithLog(uint level, string format, params object[] items)
|
public static void ConsoleWithLog(uint level, string format, params object[] items)
|
||||||
{
|
{
|
||||||
LogMessage(level, format, items);
|
LogMessage(level, format, items);
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a CecPortController
|
/// Represents a CecPortController
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CecPortController : Device, IBasicCommunicationWithStreamDebugging
|
public class CecPortController : Device, IBasicCommunicationWithStreamDebugging
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the StreamDebugging
|
/// Gets or sets the StreamDebugging
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CommunicationStreamDebugging StreamDebugging { get; private set; }
|
public CommunicationStreamDebugging StreamDebugging { get; private set; }
|
||||||
|
|
||||||
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||||
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||||
@@ -33,9 +33,9 @@ namespace PepperDash.Essentials.Core
|
|||||||
ICec Port;
|
ICec Port;
|
||||||
|
|
||||||
public CecPortController(string key, Func<EssentialsControlPropertiesConfig, ICec> postActivationFunc,
|
public CecPortController(string key, Func<EssentialsControlPropertiesConfig, ICec> postActivationFunc,
|
||||||
EssentialsControlPropertiesConfig config):base(key)
|
EssentialsControlPropertiesConfig config) : base(key)
|
||||||
{
|
{
|
||||||
StreamDebugging = new CommunicationStreamDebugging(key);
|
StreamDebugging = new CommunicationStreamDebugging(key);
|
||||||
|
|
||||||
AddPostActivationAction(() =>
|
AddPostActivationAction(() =>
|
||||||
{
|
{
|
||||||
@@ -58,27 +58,25 @@ namespace PepperDash.Essentials.Core
|
|||||||
if (args.EventId == CecEventIds.CecMessageReceivedEventId)
|
if (args.EventId == CecEventIds.CecMessageReceivedEventId)
|
||||||
OnDataReceived(cecDevice.Received.StringValue);
|
OnDataReceived(cecDevice.Received.StringValue);
|
||||||
else if (args.EventId == CecEventIds.ErrorFeedbackEventId)
|
else if (args.EventId == CecEventIds.ErrorFeedbackEventId)
|
||||||
if(cecDevice.ErrorFeedback.BoolValue)
|
if (cecDevice.ErrorFeedback.BoolValue)
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "CEC NAK Error");
|
Debug.LogMessage(LogEventLevel.Verbose, this, "CEC NAK Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnDataReceived(string s)
|
void OnDataReceived(string s)
|
||||||
{
|
{
|
||||||
var bytesHandler = BytesReceived;
|
var bytesHandler = BytesReceived;
|
||||||
if (bytesHandler != null)
|
if (bytesHandler != null)
|
||||||
{
|
{
|
||||||
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
|
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
this.PrintReceivedBytes(bytes);
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Received: '{0}'", ComTextHelper.GetEscapedText(bytes));
|
|
||||||
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||||
}
|
}
|
||||||
var textHandler = TextReceived;
|
var textHandler = TextReceived;
|
||||||
if (textHandler != null)
|
if (textHandler != null)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
this.PrintReceivedText(s);
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Received: '{0}'", s);
|
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
||||||
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IBasicCommunication Members
|
#region IBasicCommunication Members
|
||||||
@@ -90,8 +88,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
{
|
{
|
||||||
if (Port == null)
|
if (Port == null)
|
||||||
return;
|
return;
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
this.PrintSentText(text);
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Sending {0} characters of text: '{1}'", text.Length, text);
|
|
||||||
Port.StreamCec.Send.StringValue = text;
|
Port.StreamCec.Send.StringValue = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,8 +100,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
if (Port == null)
|
if (Port == null)
|
||||||
return;
|
return;
|
||||||
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
this.PrintSentBytes(bytes);
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
Debug.LogMessage(LogEventLevel.Information, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
||||||
Port.StreamCec.Send.StringValue = text;
|
Port.StreamCec.Send.StringValue = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,59 +1,78 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
using Crestron.SimplSharpPro;
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.GeneralIO;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Core.Logging;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a ComPortController
|
/// Represents a ComPortController
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ComPortController : Device, IBasicCommunicationWithStreamDebugging
|
public class ComPortController : Device, IBasicCommunicationWithStreamDebugging
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the StreamDebugging
|
/// Gets or sets the StreamDebugging
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CommunicationStreamDebugging StreamDebugging { get; private set; }
|
public CommunicationStreamDebugging StreamDebugging { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when bytes are received
|
||||||
|
/// </summary>
|
||||||
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when text is received
|
||||||
|
/// </summary>
|
||||||
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the IsConnected
|
/// Gets or sets the IsConnected
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsConnected { get { return true; } }
|
public bool IsConnected { get { return true; } }
|
||||||
|
|
||||||
ComPort Port;
|
ComPort Port;
|
||||||
ComPort.ComPortSpec Spec;
|
ComPort.ComPortSpec Spec;
|
||||||
|
|
||||||
public ComPortController(string key, Func<EssentialsControlPropertiesConfig, ComPort> postActivationFunc,
|
/// <summary>
|
||||||
ComPort.ComPortSpec spec, EssentialsControlPropertiesConfig config) : base(key)
|
/// Constructor
|
||||||
{
|
/// </summary>
|
||||||
StreamDebugging = new CommunicationStreamDebugging(key);
|
/// <param name="key"></param>
|
||||||
|
/// <param name="postActivationFunc"></param>
|
||||||
|
/// <param name="spec"></param>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
public ComPortController(string key, Func<EssentialsControlPropertiesConfig, ComPort> postActivationFunc,
|
||||||
|
ComPort.ComPortSpec spec, EssentialsControlPropertiesConfig config) : base(key)
|
||||||
|
{
|
||||||
|
StreamDebugging = new CommunicationStreamDebugging(key);
|
||||||
|
|
||||||
Spec = spec;
|
Spec = spec;
|
||||||
|
|
||||||
AddPostActivationAction(() =>
|
AddPostActivationAction(() =>
|
||||||
{
|
{
|
||||||
Port = postActivationFunc(config);
|
Port = postActivationFunc(config);
|
||||||
|
|
||||||
RegisterAndConfigureComPort();
|
RegisterAndConfigureComPort();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">Device key</param>
|
||||||
|
/// <param name="port">COM port instance</param>
|
||||||
|
/// <param name="spec">COM port specification</param>
|
||||||
public ComPortController(string key, ComPort port, ComPort.ComPortSpec spec)
|
public ComPortController(string key, ComPort port, ComPort.ComPortSpec spec)
|
||||||
: base(key)
|
: base(key)
|
||||||
{
|
{
|
||||||
if (port == null)
|
if (port == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "ERROR: Invalid com port, continuing but comms will not function");
|
Debug.LogMessage(LogEventLevel.Information, this, "ERROR: Invalid com port, continuing but comms will not function");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,71 +83,77 @@ namespace PepperDash.Essentials.Core
|
|||||||
RegisterAndConfigureComPort();
|
RegisterAndConfigureComPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterAndConfigureComPort()
|
private void RegisterAndConfigureComPort()
|
||||||
{
|
{
|
||||||
if (Port == null)
|
if (Port == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Configured com Port for this device does not exist.");
|
this.LogInformation($"Configured {Port.Parent.GetType().Name}-comport-{Port.ID} for {Key} does not exist.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Port.Parent is CrestronControlSystem)
|
|
||||||
{
|
|
||||||
var result = Port.Register();
|
|
||||||
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "ERROR: Cannot register Com port: {0}", result);
|
|
||||||
return; // false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var specResult = Port.SetComPortSpec(Spec);
|
|
||||||
if (specResult != 0)
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "WARNING: Cannot set comspec");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Port.SerialDataReceived += Port_SerialDataReceived;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ComPortController()
|
if (Port.Parent is CrestronControlSystem || Port.Parent is CenIoCom102)
|
||||||
|
{
|
||||||
|
var result = Port.Register();
|
||||||
|
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||||
|
{
|
||||||
|
this.LogError($"Cannot register {Key} using {Port.Parent.GetType().Name}-comport-{Port.ID} (result == {result})");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.LogInformation($"Successfully registered {Key} using {Port.Parent.GetType().Name}-comport-{Port.ID} (result == {result})");
|
||||||
|
}
|
||||||
|
|
||||||
|
var specResult = Port.SetComPortSpec(Spec);
|
||||||
|
if (specResult != 0)
|
||||||
|
{
|
||||||
|
this.LogError($"Cannot set comspec for {Key} using {Port.Parent.GetType().Name}-comport-{Port.ID} (result == {specResult})");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.LogInformation($"Successfully set comspec for {Key} using {Port.Parent.GetType().Name}-comport-{Port.ID} (result == {specResult})");
|
||||||
|
|
||||||
|
Port.SerialDataReceived += Port_SerialDataReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Destructor
|
||||||
|
/// </summary>
|
||||||
|
~ComPortController()
|
||||||
{
|
{
|
||||||
Port.SerialDataReceived -= Port_SerialDataReceived;
|
Port.SerialDataReceived -= Port_SerialDataReceived;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Port_SerialDataReceived(ComPort ReceivingComPort, ComPortSerialDataEventArgs args)
|
void Port_SerialDataReceived(ComPort ReceivingComPort, ComPortSerialDataEventArgs args)
|
||||||
{
|
{
|
||||||
OnDataReceived(args.SerialData);
|
OnDataReceived(args.SerialData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnDataReceived(string s)
|
void OnDataReceived(string s)
|
||||||
{
|
{
|
||||||
var eventSubscribed = false;
|
var eventSubscribed = false;
|
||||||
|
|
||||||
var bytesHandler = BytesReceived;
|
var bytesHandler = BytesReceived;
|
||||||
if (bytesHandler != null)
|
if (bytesHandler != null)
|
||||||
{
|
{
|
||||||
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
|
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
this.PrintReceivedBytes(bytes);
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Received: '{0}'", ComTextHelper.GetEscapedText(bytes));
|
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||||
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
|
||||||
eventSubscribed = true;
|
eventSubscribed = true;
|
||||||
}
|
}
|
||||||
var textHandler = TextReceived;
|
var textHandler = TextReceived;
|
||||||
if (textHandler != null)
|
if (textHandler != null)
|
||||||
{
|
{
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
this.PrintReceivedText(s);
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Received: '{0}'", s);
|
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
||||||
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
|
||||||
eventSubscribed = true;
|
eventSubscribed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!eventSubscribed) Debug.LogMessage(LogEventLevel.Warning, this, "Received data but no handler is registered");
|
if (!eventSubscribed) Debug.LogMessage(LogEventLevel.Warning, this, "Received data but no handler is registered");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deactivate method
|
/// Deactivate method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool Deactivate()
|
public override bool Deactivate()
|
||||||
{
|
{
|
||||||
return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
|
return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
|
||||||
@@ -136,70 +161,68 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
#region IBasicCommunication Members
|
#region IBasicCommunication Members
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SendText method
|
/// SendText method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendText(string text)
|
public void SendText(string text)
|
||||||
{
|
{
|
||||||
if (Port == null)
|
if (Port == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
this.PrintSentText(text);
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Sending {0} characters of text: '{1}'", text.Length, text);
|
Port.Send(text);
|
||||||
Port.Send(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SendBytes method
|
/// SendBytes method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendBytes(byte[] bytes)
|
public void SendBytes(byte[] bytes)
|
||||||
{
|
{
|
||||||
if (Port == null)
|
if (Port == null)
|
||||||
return;
|
return;
|
||||||
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
this.PrintSentBytes(bytes);
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
|
||||||
|
|
||||||
Port.Send(text);
|
Port.Send(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connect method
|
/// Connect method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Connect()
|
public void Connect()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disconnect method
|
/// Disconnect method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Disconnect()
|
public void Disconnect()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="s"></param>
|
/// <param name="s"></param>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SimulateReceive method
|
/// SimulateReceive method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SimulateReceive(string s)
|
public void SimulateReceive(string s)
|
||||||
{
|
{
|
||||||
// split out hex chars and build string
|
// split out hex chars and build string
|
||||||
var split = Regex.Split(s, @"(\\[Xx][0-9a-fA-F][0-9a-fA-F])");
|
var split = Regex.Split(s, @"(\\[Xx][0-9a-fA-F][0-9a-fA-F])");
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
foreach (var t in split)
|
foreach (var t in split)
|
||||||
{
|
{
|
||||||
if (t.StartsWith(@"\") && t.Length == 4)
|
if (t.StartsWith(@"\") && t.Length == 4)
|
||||||
b.Append((char)(Convert.ToByte(t.Substring(2, 2), 16)));
|
b.Append((char)(Convert.ToByte(t.Substring(2, 2), 16)));
|
||||||
else
|
else
|
||||||
b.Append(t);
|
b.Append(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
OnDataReceived(b.ToString());
|
OnDataReceived(b.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,8 +64,11 @@ namespace PepperDash.Essentials.Core
|
|||||||
break;
|
break;
|
||||||
case eControlMethod.Ssh:
|
case eControlMethod.Ssh:
|
||||||
{
|
{
|
||||||
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password);
|
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password)
|
||||||
ssh.AutoReconnect = c.AutoReconnect;
|
{
|
||||||
|
AutoReconnect = c.AutoReconnect,
|
||||||
|
DisableEcho = c.DisableSshEcho
|
||||||
|
};
|
||||||
if (ssh.AutoReconnect)
|
if (ssh.AutoReconnect)
|
||||||
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||||
comm = ssh;
|
comm = ssh;
|
||||||
@@ -73,8 +76,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
case eControlMethod.Tcpip:
|
case eControlMethod.Tcpip:
|
||||||
{
|
{
|
||||||
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize);
|
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize)
|
||||||
tcp.AutoReconnect = c.AutoReconnect;
|
{
|
||||||
|
AutoReconnect = c.AutoReconnect
|
||||||
|
};
|
||||||
if (tcp.AutoReconnect)
|
if (tcp.AutoReconnect)
|
||||||
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||||
comm = tcp;
|
comm = tcp;
|
||||||
@@ -90,8 +95,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
break;
|
break;
|
||||||
case eControlMethod.SecureTcpIp:
|
case eControlMethod.SecureTcpIp:
|
||||||
{
|
{
|
||||||
var secureTcp = new GenericSecureTcpIpClient(deviceConfig.Key + "-secureTcp", c.Address, c.Port, c.BufferSize);
|
var secureTcp = new GenericSecureTcpIpClient(deviceConfig.Key + "-secureTcp", c.Address, c.Port, c.BufferSize)
|
||||||
secureTcp.AutoReconnect = c.AutoReconnect;
|
{
|
||||||
|
AutoReconnect = c.AutoReconnect
|
||||||
|
};
|
||||||
if (secureTcp.AutoReconnect)
|
if (secureTcp.AutoReconnect)
|
||||||
secureTcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
secureTcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||||
comm = secureTcp;
|
comm = secureTcp;
|
||||||
|
|||||||
@@ -127,19 +127,32 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var doubleObj = JObject.Parse(fs.ReadToEnd());
|
var parsedConfig = JObject.Parse(fs.ReadToEnd());
|
||||||
ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
|
|
||||||
|
|
||||||
// Extract SystemUrl and TemplateUrl into final config output
|
// 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 (doubleObj["system_url"] != 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>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,86 +11,169 @@ using PepperDash.Core;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Config
|
namespace PepperDash.Essentials.Core.Config
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the ConfigObject from the file
|
/// Loads the ConfigObject from the file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsConfig : BasicConfig
|
public class EssentialsConfig : BasicConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("system_url")]
|
/// <summary>
|
||||||
|
/// Gets or sets the SystemUrl
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("system_url")]
|
||||||
public string SystemUrl { get; set; }
|
public string SystemUrl { get; set; }
|
||||||
|
|
||||||
[JsonProperty("template_url")]
|
/// <summary>
|
||||||
|
/// Gets or sets the TemplateUrl
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("template_url")]
|
||||||
public string TemplateUrl { get; set; }
|
public string TemplateUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the SystemUuid extracted from the SystemUrl
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("systemUuid")]
|
[JsonProperty("systemUuid")]
|
||||||
public string SystemUuid
|
public string SystemUuid
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(SystemUrl))
|
string uuid;
|
||||||
return "missing url";
|
|
||||||
|
|
||||||
if (SystemUrl.Contains("#"))
|
if (string.IsNullOrEmpty(SystemUrl))
|
||||||
{
|
{
|
||||||
var result = Regex.Match(SystemUrl, @"https?:\/\/.*\/systems\/(.*)\/#.*");
|
uuid = "missing url";
|
||||||
string uuid = result.Groups[1].Value;
|
}
|
||||||
return uuid;
|
else if (SystemUrl.Contains("#"))
|
||||||
} else
|
{
|
||||||
{
|
var result = Regex.Match(SystemUrl, @"https?:\/\/.*\/systems\/(.*)\/#.*");
|
||||||
|
uuid = result.Groups[1].Value;
|
||||||
|
}
|
||||||
|
else if (SystemUrl.Contains("detail"))
|
||||||
|
{
|
||||||
|
var result = Regex.Match(SystemUrl, @"https?:\/\/.*\/systems\/detail\/(.*)\/.*");
|
||||||
|
uuid = result.Groups[1].Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
var result = Regex.Match(SystemUrl, @"https?:\/\/.*\/systems\/(.*)\/.*");
|
var result = Regex.Match(SystemUrl, @"https?:\/\/.*\/systems\/(.*)\/.*");
|
||||||
string uuid = result.Groups[1].Value;
|
uuid = result.Groups[1].Value;
|
||||||
return uuid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return uuid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the TemplateUuid extracted from the TemplateUrl
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("templateUuid")]
|
[JsonProperty("templateUuid")]
|
||||||
public string TemplateUuid
|
public string TemplateUuid
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(TemplateUrl))
|
string uuid;
|
||||||
return "missing template url";
|
|
||||||
|
|
||||||
if (TemplateUrl.Contains("#"))
|
if (string.IsNullOrEmpty(TemplateUrl))
|
||||||
{
|
{
|
||||||
var result = Regex.Match(TemplateUrl, @"https?:\/\/.*\/templates\/(.*)\/#.*");
|
uuid = "missing template url";
|
||||||
string uuid = result.Groups[1].Value;
|
|
||||||
return uuid;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
var result = Regex.Match(TemplateUrl, @"https?:\/\/.*\/system-templates\/(.*)\/system-template-versions\/(.*)\/.*");
|
|
||||||
string uuid = result.Groups[2].Value;
|
|
||||||
return uuid;
|
|
||||||
}
|
}
|
||||||
|
else if (TemplateUrl.Contains("#"))
|
||||||
|
{
|
||||||
|
var result = Regex.Match(TemplateUrl, @"https?:\/\/.*\/templates\/(.*)\/#.*");
|
||||||
|
uuid = result.Groups[1].Value;
|
||||||
|
}
|
||||||
|
else if (TemplateUrl.Contains("detail"))
|
||||||
|
{
|
||||||
|
var result = Regex.Match(TemplateUrl, @"https?:\/\/.*\/system-templates\/detail\/(.*)\/system-template-versions\/detail\/(.*)\/.*");
|
||||||
|
uuid = result.Groups[2].Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var result = Regex.Match(TemplateUrl, @"https?:\/\/.*\/system-templates\/(.*)\/system-template-versions\/(.*)\/.*");
|
||||||
|
uuid = result.Groups[2].Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uuid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonProperty("rooms")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Rooms
|
/// Gets or sets the Rooms
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("rooms")]
|
||||||
public List<DeviceConfig> Rooms { get; set; }
|
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()
|
public EssentialsConfig()
|
||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
Rooms = new List<DeviceConfig>();
|
Rooms = new List<DeviceConfig>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a SystemTemplateConfigs
|
/// Represents version data for Essentials and its packages
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SystemTemplateConfigs
|
public class VersionData
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the System
|
/// Gets or sets the Essentials version
|
||||||
/// </summary>
|
/// </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>
|
||||||
public EssentialsConfig System { get; set; }
|
public EssentialsConfig System { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Template
|
||||||
|
/// </summary>
|
||||||
public EssentialsConfig Template { get; set; }
|
public EssentialsConfig Template { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,9 +60,9 @@ namespace PepperDash.Essentials.Core
|
|||||||
ConsoleAccessLevelEnum.AccessOperator);
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
|
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
|
||||||
ConsoleAccessLevelEnum.AccessOperator);
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s)), "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
|
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s).Replace(Environment.NewLine, "\r\n")), "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s)), "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s).Replace(Environment.NewLine, "\r\n")), "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s)), "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s).Replace(Environment.NewLine, "\r\n")), "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
|
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
|
||||||
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
|
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
|
|||||||
@@ -16,121 +16,201 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Processor Attributes
|
// Processor Attributes
|
||||||
|
/// <summary>
|
||||||
|
/// Processor IP 1
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorIp1")]
|
[JoinName("ProcessorIp1")]
|
||||||
public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Info - Processor - IP 1" },
|
public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Info - Processor - IP 1" },
|
||||||
new JoinMetadata { Description = "Info - Processor - IP 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - IP 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor IP 2
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorIp2")]
|
[JoinName("ProcessorIp2")]
|
||||||
public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1, AttributeName = "Info - Processor - IP 2" },
|
public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1, AttributeName = "Info - Processor - IP 2" },
|
||||||
new JoinMetadata { Description = "Info - Processor - IP 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - IP 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor Gateway
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorGateway")]
|
[JoinName("ProcessorGateway")]
|
||||||
public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1, AttributeName = "Info - Processor - Gateway" },
|
public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1, AttributeName = "Info - Processor - Gateway" },
|
||||||
new JoinMetadata { Description = "Info - Processor - Gateway", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - Gateway", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor Hostname
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorHostname")]
|
[JoinName("ProcessorHostname")]
|
||||||
public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1, AttributeName = "Info - Processor - Hostname" },
|
public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1, AttributeName = "Info - Processor - Hostname" },
|
||||||
new JoinMetadata { Description = "Info - Processor - Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor Domain
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorDomain")]
|
[JoinName("ProcessorDomain")]
|
||||||
public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 54, JoinSpan = 1, AttributeName = "Info - Processor - Domain" },
|
public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 54, JoinSpan = 1, AttributeName = "Info - Processor - Domain" },
|
||||||
new JoinMetadata { Description = "Info - Processor - Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor DNS 1
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorDns1")]
|
[JoinName("ProcessorDns1")]
|
||||||
public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - DNS 1" },
|
public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - DNS 1" },
|
||||||
new JoinMetadata { Description = "Info - Processor - DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor DNS 2
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorDns2")]
|
[JoinName("ProcessorDns2")]
|
||||||
public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1, AttributeName = "Info - Processor - DNS 2" },
|
public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1, AttributeName = "Info - Processor - DNS 2" },
|
||||||
new JoinMetadata { Description = "Info - Processor - DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor MAC 1
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorMac1")]
|
[JoinName("ProcessorMac1")]
|
||||||
public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1, AttributeName = "Info - Processor - MAC 1" },
|
public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1, AttributeName = "Info - Processor - MAC 1" },
|
||||||
new JoinMetadata { Description = "Info - Processor - MAC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - MAC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor MAC 2
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorMac2")]
|
[JoinName("ProcessorMac2")]
|
||||||
public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1, AttributeName = "Info - Processor - MAC 2" },
|
public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1, AttributeName = "Info - Processor - MAC 2" },
|
||||||
new JoinMetadata { Description = "Info - Processor - MAC 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - MAC 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor Net Mask 1
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorNetMask1")]
|
[JoinName("ProcessorNetMask1")]
|
||||||
public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 1" },
|
public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 1" },
|
||||||
new JoinMetadata { Description = "Info - Processor - Net Mask 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - Net Mask 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor Net Mask 2
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorNetMask2")]
|
[JoinName("ProcessorNetMask2")]
|
||||||
public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 2" },
|
public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 2" },
|
||||||
new JoinMetadata { Description = "Info - Processor - Net Mask 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - Net Mask 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor Firmware
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorFirmware")]
|
[JoinName("ProcessorFirmware")]
|
||||||
public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1, AttributeName = "Info - Processor - Firmware" },
|
public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1, AttributeName = "Info - Processor - Firmware" },
|
||||||
new JoinMetadata { Description = "Info - Processor - Firmware", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - Firmware", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Program Name Start
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProgramNameStart")]
|
[JoinName("ProgramNameStart")]
|
||||||
public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10, AttributeName = "Info - Processor - Program" },
|
public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10, AttributeName = "Info - Processor - Program" },
|
||||||
new JoinMetadata { Description = "Info - Processor - Program", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Info - Processor - Program", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processor Reboot
|
||||||
|
/// </summary>
|
||||||
[JoinName("ProcessorReboot")]
|
[JoinName("ProcessorReboot")]
|
||||||
public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1, AttributeName = "Processor - Reboot" },
|
public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1, AttributeName = "Processor - Reboot" },
|
||||||
new JoinMetadata { Description = "Processor - Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital });
|
new JoinMetadata { Description = "Processor - Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
// Volume Controls
|
// Volume Controls
|
||||||
|
/// <summary>
|
||||||
|
/// Volume Fader 1
|
||||||
|
/// </summary>
|
||||||
[JoinName("VolumeFader1")]
|
[JoinName("VolumeFader1")]
|
||||||
public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Volume - Fader01" },
|
public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Volume - Fader01" },
|
||||||
new JoinMetadata { Description = "Volume - Fader01", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog });
|
new JoinMetadata { Description = "Volume - Fader01", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog });
|
||||||
|
|
||||||
// Codec Info
|
// Codec Info
|
||||||
|
/// <summary>
|
||||||
|
/// VC Codec In Call
|
||||||
|
/// </summary>
|
||||||
[JoinName("VcCodecInCall")]
|
[JoinName("VcCodecInCall")]
|
||||||
public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1, AttributeName = "Conf - VC 1 In Call" },
|
public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1, AttributeName = "Conf - VC 1 In Call" },
|
||||||
new JoinMetadata { Description = "Conf - VC 1 In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
new JoinMetadata { Description = "Conf - VC 1 In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// VC Codec Online
|
||||||
|
/// </summary>
|
||||||
[JoinName("VcCodecOnline")]
|
[JoinName("VcCodecOnline")]
|
||||||
public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1, AttributeName = "Online - VC 1" },
|
public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1, AttributeName = "Online - VC 1" },
|
||||||
new JoinMetadata { Description = "Online - VC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
new JoinMetadata { Description = "Online - VC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// VC Codec IP Address
|
||||||
|
/// </summary>
|
||||||
[JoinName("VcCodecIpAddress")]
|
[JoinName("VcCodecIpAddress")]
|
||||||
public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1, AttributeName = "IP Address - VC" },
|
public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1, AttributeName = "IP Address - VC" },
|
||||||
new JoinMetadata { Description = "IP Address - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "IP Address - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// VC Codec IP Port
|
||||||
|
/// </summary>
|
||||||
[JoinName("VcCodecIpPort")]
|
[JoinName("VcCodecIpPort")]
|
||||||
public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1, AttributeName = "IP Port - VC" },
|
public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1, AttributeName = "IP Port - VC" },
|
||||||
new JoinMetadata { Description = "IP Port - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "IP Port - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
// Source Attributes
|
// Source Attributes
|
||||||
|
/// <summary>
|
||||||
|
/// Display 1 Current Source Name
|
||||||
|
/// </summary>
|
||||||
[JoinName("Display1CurrentSourceName")]
|
[JoinName("Display1CurrentSourceName")]
|
||||||
public JoinDataComplete Display1CurrentSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1, AttributeName = "Display 1 - Current Source" },
|
public JoinDataComplete Display1CurrentSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1, AttributeName = "Display 1 - Current Source" },
|
||||||
new JoinMetadata { Description = "Display 1 - Current Source", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "Display 1 - Current Source", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||||
|
|
||||||
|
|
||||||
// Device Online Status
|
// Device Online Status
|
||||||
|
/// <summary>
|
||||||
|
/// Touchpanel Online Start
|
||||||
|
/// </summary>
|
||||||
[JoinName("TouchpanelOnlineStart")]
|
[JoinName("TouchpanelOnlineStart")]
|
||||||
public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10, AttributeName = "Online - Touch Panel" },
|
public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10, AttributeName = "Online - Touch Panel" },
|
||||||
new JoinMetadata { Description = "Online - Touch Panel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
new JoinMetadata { Description = "Online - Touch Panel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Xpanel Online Start
|
||||||
|
/// </summary>
|
||||||
[JoinName("XpanelOnlineStart")]
|
[JoinName("XpanelOnlineStart")]
|
||||||
public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5, AttributeName = "Online - XPanel" },
|
public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5, AttributeName = "Online - XPanel" },
|
||||||
new JoinMetadata { Description = "Online - XPanel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
new JoinMetadata { Description = "Online - XPanel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display Online Start
|
||||||
|
/// </summary>
|
||||||
[JoinName("DisplayOnlineStart")]
|
[JoinName("DisplayOnlineStart")]
|
||||||
public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10, AttributeName = "Online - Display" },
|
public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10, AttributeName = "Online - Display" },
|
||||||
new JoinMetadata { Description = "Online - Display", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
new JoinMetadata { Description = "Online - Display", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display 1 Laptop Source Start
|
||||||
|
/// </summary>
|
||||||
[JoinName("Display1LaptopSourceStart")]
|
[JoinName("Display1LaptopSourceStart")]
|
||||||
public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 5, AttributeName = "Display 1 - Source Laptop" },
|
public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 165, JoinSpan = 5, AttributeName = "Display 1 - Source Laptop" },
|
||||||
new JoinMetadata { Description = "Display 1 - Source Laptop", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
new JoinMetadata { Description = "Display 1 - Source Laptop", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display 1 Disc Player Source Start
|
||||||
|
/// </summary>
|
||||||
[JoinName("Display1DiscPlayerSourceStart")]
|
[JoinName("Display1DiscPlayerSourceStart")]
|
||||||
public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 181, JoinSpan = 5, AttributeName = "Display 1 - Source Disc Player" },
|
public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 180, JoinSpan = 5, AttributeName = "Display 1 - Source Disc Player" },
|
||||||
new JoinMetadata { Description = "Display 1 - Source Disc Player", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
new JoinMetadata { Description = "Display 1 - Source Disc Player", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display 1 Set Top Box Source Start
|
||||||
|
/// </summary>
|
||||||
[JoinName("Display1SetTopBoxSourceStart")]
|
[JoinName("Display1SetTopBoxSourceStart")]
|
||||||
public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5, AttributeName = "Display 1 - Source TV" },
|
public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 185, JoinSpan = 5, AttributeName = "Display 1 - Source TV" },
|
||||||
new JoinMetadata { Description = "Display 1 - Source TV", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
new JoinMetadata { Description = "Display 1 - Source TV", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
// Display 1
|
// Display 1
|
||||||
|
/// <summary>
|
||||||
|
/// Display 1 Start
|
||||||
|
/// </summary>
|
||||||
[JoinName("Display1Start")]
|
[JoinName("Display1Start")]
|
||||||
public JoinDataComplete Display1Start = new JoinDataComplete(new JoinData { JoinNumber = 158, JoinSpan = 1 },
|
public JoinDataComplete Display1Start = new JoinDataComplete(new JoinData { JoinNumber = 190, JoinSpan = 1 },
|
||||||
new JoinMetadata { Description = "Display 1 Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
new JoinMetadata { Description = "Display 1 Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor to use when instantiating this Join Map without inheriting from it
|
/// Constructor to use when instantiating this Join Map without inheriting from it
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
using Crestron.SimplSharp.CrestronIO;
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
using Crestron.SimplSharp.CrestronXml;
|
using Crestron.SimplSharp.CrestronXml;
|
||||||
using Crestron.SimplSharp.CrestronXml.Serialization;
|
using Crestron.SimplSharp.CrestronXml.Serialization;
|
||||||
@@ -8,6 +6,7 @@ using Crestron.SimplSharpPro;
|
|||||||
using Crestron.SimplSharpPro.Fusion;
|
using Crestron.SimplSharpPro.Fusion;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Core.Logging;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
@@ -21,26 +20,42 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a EssentialsHuddleSpaceFusionSystemControllerBase
|
/// Represents a EssentialsHuddleSpaceFusionSystemControllerBase
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider
|
public class IEssentialsRoomFusionController : EssentialsDevice, IOccupancyStatusProvider, IFusionHelpRequest
|
||||||
{
|
{
|
||||||
private readonly EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap;
|
private IEssentialsRoomFusionControllerPropertiesConfig _config;
|
||||||
|
|
||||||
|
private EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap;
|
||||||
|
|
||||||
private const string RemoteOccupancyXml = "<Occupancy><Type>Local</Type><State>{0}</State></Occupancy>";
|
private const string RemoteOccupancyXml = "<Occupancy><Type>Local</Type><State>{0}</State></Occupancy>";
|
||||||
private readonly bool _guidFileExists;
|
private bool _guidFileExists;
|
||||||
|
|
||||||
private readonly Dictionary<Device, BoolInputSig> _sourceToFeedbackSigs =
|
private readonly Dictionary<Device, BoolInputSig> _sourceToFeedbackSigs =
|
||||||
new Dictionary<Device, BoolInputSig>();
|
new Dictionary<Device, BoolInputSig>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the CurrentRoomSourceNameSig
|
||||||
|
/// </summary>
|
||||||
protected StringSigData CurrentRoomSourceNameSig;
|
protected StringSigData CurrentRoomSourceNameSig;
|
||||||
|
|
||||||
private readonly FusionCustomPropertiesBridge CustomPropertiesBridge = new FusionCustomPropertiesBridge();
|
private readonly FusionCustomPropertiesBridge CustomPropertiesBridge = new FusionCustomPropertiesBridge();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the FusionOccSensor
|
||||||
|
/// </summary>
|
||||||
protected FusionOccupancySensorAsset FusionOccSensor;
|
protected FusionOccupancySensorAsset FusionOccSensor;
|
||||||
private readonly FusionRemoteOccupancySensor FusionRemoteOccSensor;
|
private readonly FusionRemoteOccupancySensor FusionRemoteOccSensor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the FusionRoom
|
||||||
|
/// </summary>
|
||||||
protected FusionRoom FusionRoom;
|
protected FusionRoom FusionRoom;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the FusionStaticAssets
|
||||||
|
/// </summary>
|
||||||
protected Dictionary<int, FusionAsset> FusionStaticAssets;
|
protected Dictionary<int, FusionAsset> FusionStaticAssets;
|
||||||
private readonly long PushNotificationTimeout = 5000;
|
private readonly long PushNotificationTimeout = 5000;
|
||||||
private readonly IEssentialsRoom Room;
|
private IEssentialsRoom Room;
|
||||||
private readonly long SchedulePollInterval = 300000;
|
private readonly long SchedulePollInterval = 300000;
|
||||||
|
|
||||||
private Event _currentMeeting;
|
private Event _currentMeeting;
|
||||||
@@ -48,8 +63,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
private CTimer _dailyTimeRequestTimer;
|
private CTimer _dailyTimeRequestTimer;
|
||||||
private StatusMonitorCollection _errorMessageRollUp;
|
private StatusMonitorCollection _errorMessageRollUp;
|
||||||
|
|
||||||
private FusionRoomGuids _guiDs;
|
private FusionRoomGuids _guids;
|
||||||
private uint _ipId;
|
|
||||||
|
|
||||||
private bool _isRegisteredForSchedulePushNotifications;
|
private bool _isRegisteredForSchedulePushNotifications;
|
||||||
private Event _nextMeeting;
|
private Event _nextMeeting;
|
||||||
@@ -60,6 +74,20 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
private string _roomOccupancyRemoteString;
|
private string _roomOccupancyRemoteString;
|
||||||
|
|
||||||
|
private bool _helpRequestSent;
|
||||||
|
|
||||||
|
private eFusionHelpResponse _helpRequestStatus;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public StringFeedback HelpRequestResponseFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public BoolFeedback HelpRequestSentFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public StringFeedback HelpRequestStatusFeedback { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
#region System Info Sigs
|
#region System Info Sigs
|
||||||
|
|
||||||
//StringSigData SystemName;
|
//StringSigData SystemName;
|
||||||
@@ -93,17 +121,88 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public EssentialsHuddleSpaceFusionSystemControllerBase(IEssentialsRoom room, uint ipId, string joinMapKey)
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
|
public IEssentialsRoomFusionController(string key, string name, IEssentialsRoomFusionControllerPropertiesConfig config)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
_config = config;
|
||||||
|
|
||||||
|
AddPostActivationAction(() =>
|
||||||
|
{
|
||||||
|
var room = DeviceManager.GetDeviceForKey<IEssentialsRoom>(_config.RoomKey);
|
||||||
|
|
||||||
|
if (room == null)
|
||||||
|
{
|
||||||
|
this.LogError("Error Creating Fusion Room Controller. No room found with key '{0}'", _config.RoomKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.LogInformation("Creating Fusion Room Controller for room '{0}' at IPID: {1:X2}", room.Key, _config.IpIdInt);
|
||||||
|
|
||||||
|
ConstructorHelper(room, _config.IpIdInt, _config.JoinMapKey);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="room"></param>
|
||||||
|
/// <param name="ipId"></param>
|
||||||
|
/// <param name="joinMapKey"></param>
|
||||||
|
public IEssentialsRoomFusionController(IEssentialsRoom room, string ipId, string joinMapKey)
|
||||||
: base(room.Key + "-fusion")
|
: base(room.Key + "-fusion")
|
||||||
|
{
|
||||||
|
_config = new IEssentialsRoomFusionControllerPropertiesConfig()
|
||||||
|
{
|
||||||
|
IpId = ipId,
|
||||||
|
RoomKey = room.Key,
|
||||||
|
JoinMapKey = joinMapKey
|
||||||
|
};
|
||||||
|
|
||||||
|
ConstructorHelper(room, _config.IpIdInt, joinMapKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConstructorHelper(IEssentialsRoom room, uint ipId, string joinMapKey)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
this.LogDebug("ConstructorHelper called for Fusion Room Controller for room '{0}' with IPID {1:X2}", room.Key, ipId);
|
||||||
|
|
||||||
|
this.LogDebug("JoinMap Key: {0}", joinMapKey);
|
||||||
|
|
||||||
JoinMap = new EssentialsHuddleSpaceRoomFusionRoomJoinMap(1);
|
JoinMap = new EssentialsHuddleSpaceRoomFusionRoomJoinMap(1);
|
||||||
|
|
||||||
CrestronConsole.AddNewConsoleCommand((o) => JoinMap.PrintJoinMapInfo(), string.Format("ptjnmp-{0}", Key), "Prints Attribute Join Map", ConsoleAccessLevelEnum.AccessOperator);
|
this.LogDebug("JoinMap created");
|
||||||
|
|
||||||
|
CrestronConsole.AddNewConsoleCommand((o) =>
|
||||||
|
{
|
||||||
|
if (o is string deviceKey)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(deviceKey) || deviceKey == "?")
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse("Please provide a device key for a Fusion Room instance");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (deviceKey != this.Key)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse("Invalid parameter. Please provide a device key for a Fusion Room instance");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JoinMap.PrintJoinMapInfo();
|
||||||
|
}, "printfusionjoinmap", "Prints Attribute Join Map", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(joinMapKey))
|
if (!string.IsNullOrEmpty(joinMapKey))
|
||||||
{
|
{
|
||||||
|
// this.LogDebug("Attempting to get custom join map for key: {0}", joinMapKey);
|
||||||
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
|
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
|
||||||
if (customJoins != null)
|
if (customJoins != null)
|
||||||
{
|
{
|
||||||
@@ -113,51 +212,19 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
Room = room;
|
Room = room;
|
||||||
|
|
||||||
_ipId = ipId;
|
this.LogDebug("Room found: {0}", Room.Key);
|
||||||
|
|
||||||
FusionStaticAssets = new Dictionary<int, FusionAsset>();
|
FusionStaticAssets = new Dictionary<int, FusionAsset>();
|
||||||
|
|
||||||
_guiDs = new FusionRoomGuids();
|
this.LogDebug("FusionStaticAssets dictionary created");
|
||||||
|
|
||||||
var mac =
|
_guids = new FusionRoomGuids();
|
||||||
CrestronEthernetHelper.GetEthernetParameter(
|
|
||||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0);
|
|
||||||
|
|
||||||
var slot = Global.ControlSystem.ProgramNumber;
|
|
||||||
|
|
||||||
var guidFilePath = Global.FilePathPrefix +
|
|
||||||
string.Format(@"{0}-FusionGuids-{1:X2}.json", InitialParametersClass.ProgramIDTag, _ipId);
|
|
||||||
|
|
||||||
var oldGuidFilePath = Global.FilePathPrefix +
|
|
||||||
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
|
||||||
|
|
||||||
if (File.Exists(oldGuidFilePath))
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Migrating from old Fusion GUID file to new Fusion GUID File");
|
|
||||||
|
|
||||||
File.Copy(oldGuidFilePath, guidFilePath);
|
|
||||||
|
|
||||||
File.Delete(oldGuidFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
_guidFileExists = File.Exists(guidFilePath);
|
|
||||||
|
|
||||||
// Check if file exists
|
|
||||||
if (!_guidFileExists)
|
|
||||||
{
|
|
||||||
// Does not exist. Create GUIDs
|
|
||||||
_guiDs = new FusionRoomGuids(Room.Name, ipId, _guiDs.GenerateNewRoomGuid(slot, mac),
|
|
||||||
FusionStaticAssets);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Exists. Read GUIDs
|
|
||||||
ReadGuidFile(guidFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this.LogDebug("FusionRoomGuids created");
|
||||||
|
|
||||||
if (Room is IRoomOccupancy occupancyRoom)
|
if (Room is IRoomOccupancy occupancyRoom)
|
||||||
{
|
{
|
||||||
|
Debug.LogDebug(this, "Room '{0}' supports IRoomOccupancy", Room.Key);
|
||||||
if (occupancyRoom.RoomOccupancy != null)
|
if (occupancyRoom.RoomOccupancy != null)
|
||||||
{
|
{
|
||||||
if (occupancyRoom.OccupancyStatusProviderIsRemote)
|
if (occupancyRoom.OccupancyStatusProviderIsRemote)
|
||||||
@@ -171,8 +238,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.LogDebug("Occupancy setup complete");
|
||||||
|
|
||||||
AddPostActivationAction(() => PostActivate(guidFilePath));
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -180,9 +247,54 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PostActivate(string guidFilePath)
|
private string GetGuidFilePath(uint ipId)
|
||||||
{
|
{
|
||||||
CreateSymbolAndBasicSigs(_ipId);
|
var mac =
|
||||||
|
CrestronEthernetHelper.GetEthernetParameter(
|
||||||
|
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0);
|
||||||
|
|
||||||
|
var slot = Global.ControlSystem.ProgramNumber;
|
||||||
|
|
||||||
|
var guidFilePath = Global.FilePathPrefix +
|
||||||
|
string.Format(@"{0}-FusionGuids-{1:X2}.json", InitialParametersClass.ProgramIDTag, _config.IpIdInt);
|
||||||
|
|
||||||
|
var oldGuidFilePath = Global.FilePathPrefix +
|
||||||
|
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
||||||
|
|
||||||
|
if (File.Exists(oldGuidFilePath))
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, this, "Migrating from old Fusion GUID file to new Fusion GUID File");
|
||||||
|
|
||||||
|
File.Copy(oldGuidFilePath, guidFilePath);
|
||||||
|
|
||||||
|
File.Delete(oldGuidFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
_guidFileExists = File.Exists(guidFilePath);
|
||||||
|
|
||||||
|
// Check if file exists
|
||||||
|
if (!_guidFileExists)
|
||||||
|
{
|
||||||
|
// Does not exist. Create GUIDs
|
||||||
|
_guids = new FusionRoomGuids(Room.Name, ipId, _guids.GenerateNewRoomGuid(slot, mac),
|
||||||
|
FusionStaticAssets);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Exists. Read GUIDs
|
||||||
|
ReadGuidFile(guidFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return guidFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
GenerateGuidFile(GetGuidFilePath(_config.IpIdInt));
|
||||||
|
|
||||||
|
CreateSymbolAndBasicSigs(_config.IpIdInt);
|
||||||
SetUpSources();
|
SetUpSources();
|
||||||
SetUpCommunitcationMonitors();
|
SetUpCommunitcationMonitors();
|
||||||
SetUpDisplay();
|
SetUpDisplay();
|
||||||
@@ -191,12 +303,18 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
FusionRVI.GenerateFileForAllFusionDevices();
|
FusionRVI.GenerateFileForAllFusionDevices();
|
||||||
|
|
||||||
GenerateGuidFile(guidFilePath);
|
HelpRequestResponseFeedback = new StringFeedback("HelpRequestResponse", () => FusionRoom.Help.OutputSig.StringValue);
|
||||||
|
|
||||||
|
HelpRequestSentFeedback = new BoolFeedback("HelpRequestSent", () => _helpRequestSent);
|
||||||
|
HelpRequestStatusFeedback = new StringFeedback("HelpRequestStatus", () => _helpRequestStatus.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the RoomGuid
|
||||||
|
/// </summary>
|
||||||
protected string RoomGuid
|
protected string RoomGuid
|
||||||
{
|
{
|
||||||
get { return _guiDs.RoomGuid; }
|
get { return _guids.RoomGuid; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -204,6 +322,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public StringFeedback RoomOccupancyRemoteStringFeedback { get; private set; }
|
public StringFeedback RoomOccupancyRemoteStringFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the RoomIsOccupiedFeedbackFunc
|
||||||
|
/// </summary>
|
||||||
protected Func<bool> RoomIsOccupiedFeedbackFunc
|
protected Func<bool> RoomIsOccupiedFeedbackFunc
|
||||||
{
|
{
|
||||||
get { return () => FusionRemoteOccSensor.RoomOccupied.OutputSig.BoolValue; }
|
get { return () => FusionRemoteOccSensor.RoomOccupied.OutputSig.BoolValue; }
|
||||||
@@ -218,10 +339,16 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ScheduleChange event
|
||||||
|
/// </summary>
|
||||||
public event EventHandler<ScheduleChangeEventArgs> ScheduleChange;
|
public event EventHandler<ScheduleChangeEventArgs> ScheduleChange;
|
||||||
//public event EventHandler<MeetingChangeEventArgs> MeetingEndWarning;
|
//public event EventHandler<MeetingChangeEventArgs> MeetingEndWarning;
|
||||||
//public event EventHandler<MeetingChangeEventArgs> NextMeetingBeginWarning;
|
//public event EventHandler<MeetingChangeEventArgs> NextMeetingBeginWarning;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// RoomInfoChange event
|
||||||
|
/// </summary>
|
||||||
public event EventHandler<EventArgs> RoomInfoChange;
|
public event EventHandler<EventArgs> RoomInfoChange;
|
||||||
|
|
||||||
//ScheduleResponseEvent NextMeeting;
|
//ScheduleResponseEvent NextMeeting;
|
||||||
@@ -258,11 +385,11 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "Writing GUIDs to file");
|
Debug.LogMessage(LogEventLevel.Debug, this, "Writing GUIDs to file");
|
||||||
|
|
||||||
_guiDs = FusionOccSensor == null
|
_guids = FusionOccSensor == null
|
||||||
? new FusionRoomGuids(Room.Name, _ipId, RoomGuid, FusionStaticAssets)
|
? new FusionRoomGuids(Room.Name, _config.IpIdInt, RoomGuid, FusionStaticAssets)
|
||||||
: new FusionRoomGuids(Room.Name, _ipId, RoomGuid, FusionStaticAssets, FusionOccSensor);
|
: new FusionRoomGuids(Room.Name, _config.IpIdInt, RoomGuid, FusionStaticAssets, FusionOccSensor);
|
||||||
|
|
||||||
var json = JsonConvert.SerializeObject(_guiDs, Newtonsoft.Json.Formatting.Indented);
|
var json = JsonConvert.SerializeObject(_guids, Newtonsoft.Json.Formatting.Indented);
|
||||||
|
|
||||||
using (var sw = new StreamWriter(filePath))
|
using (var sw = new StreamWriter(filePath))
|
||||||
{
|
{
|
||||||
@@ -312,17 +439,17 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
{
|
{
|
||||||
var json = File.ReadToEnd(filePath, Encoding.ASCII);
|
var json = File.ReadToEnd(filePath, Encoding.ASCII);
|
||||||
|
|
||||||
_guiDs = JsonConvert.DeserializeObject<FusionRoomGuids>(json);
|
_guids = JsonConvert.DeserializeObject<FusionRoomGuids>(json);
|
||||||
|
|
||||||
_ipId = _guiDs.IpId;
|
// _config.IpId = _guids.IpId;
|
||||||
|
|
||||||
FusionStaticAssets = _guiDs.StaticAssets;
|
FusionStaticAssets = _guids.StaticAssets;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Fusion Guids successfully read from file: {0}",
|
Debug.LogMessage(LogEventLevel.Information, this, "Fusion Guids successfully read from file: {0}",
|
||||||
filePath);
|
filePath);
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "\r\n********************\r\n\tRoom Name: {0}\r\n\tIPID: {1:X}\r\n\tRoomGuid: {2}\r\n*******************", Room.Name, _ipId, RoomGuid);
|
Debug.LogMessage(LogEventLevel.Debug, this, "\r\n********************\r\n\tRoom Name: {0}\r\n\tIPID: {1:X}\r\n\tRoomGuid: {2}\r\n*******************", Room.Name, _config.IpIdInt, RoomGuid);
|
||||||
|
|
||||||
foreach (var item in FusionStaticAssets)
|
foreach (var item in FusionStaticAssets)
|
||||||
{
|
{
|
||||||
@@ -343,6 +470,10 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// CreateSymbolAndBasicSigs method
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipId"></param>
|
||||||
protected virtual void CreateSymbolAndBasicSigs(uint ipId)
|
protected virtual void CreateSymbolAndBasicSigs(uint ipId)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
|
Debug.LogMessage(LogEventLevel.Information, this, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
|
||||||
@@ -405,6 +536,10 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// CrestronEnvironment_EthernetEventHandler method
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ethernetEventArgs"></param>
|
||||||
protected void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs)
|
protected void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs)
|
||||||
{
|
{
|
||||||
if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp)
|
if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp)
|
||||||
@@ -413,6 +548,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GetSystemInfo method
|
||||||
|
/// </summary>
|
||||||
protected void GetSystemInfo()
|
protected void GetSystemInfo()
|
||||||
{
|
{
|
||||||
//SystemName.InputSig.StringValue = Room.Name;
|
//SystemName.InputSig.StringValue = Room.Name;
|
||||||
@@ -426,6 +564,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
() => CrestronConsole.SendControlSystemCommand("reboot", ref response));
|
() => CrestronConsole.SendControlSystemCommand("reboot", ref response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SetUpEthernetValues method
|
||||||
|
/// </summary>
|
||||||
protected void SetUpEthernetValues()
|
protected void SetUpEthernetValues()
|
||||||
{
|
{
|
||||||
_ip1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp1.JoinNumber, JoinMap.ProcessorIp1.AttributeName, eSigIoMask.InputSigOnly);
|
_ip1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp1.JoinNumber, JoinMap.ProcessorIp1.AttributeName, eSigIoMask.InputSigOnly);
|
||||||
@@ -441,6 +582,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
_netMask2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask2.JoinNumber, JoinMap.ProcessorNetMask2.AttributeName, eSigIoMask.InputSigOnly);
|
_netMask2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask2.JoinNumber, JoinMap.ProcessorNetMask2.AttributeName, eSigIoMask.InputSigOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GetProcessorEthernetValues method
|
||||||
|
/// </summary>
|
||||||
protected void GetProcessorEthernetValues()
|
protected void GetProcessorEthernetValues()
|
||||||
{
|
{
|
||||||
_ip1.InputSig.StringValue =
|
_ip1.InputSig.StringValue =
|
||||||
@@ -475,7 +619,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
// Interface 1
|
// Interface 1
|
||||||
|
|
||||||
if (InitialParametersClass.NumberOfEthernetInterfaces > 1)
|
if (InitialParametersClass.NumberOfEthernetInterfaces > 1)
|
||||||
// Only get these values if the processor has more than 1 NIC
|
// Only get these values if the processor has more than 1 NIC
|
||||||
{
|
{
|
||||||
_ip2.InputSig.StringValue =
|
_ip2.InputSig.StringValue =
|
||||||
CrestronEthernetHelper.GetEthernetParameter(
|
CrestronEthernetHelper.GetEthernetParameter(
|
||||||
@@ -489,6 +633,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GetProcessorInfo method
|
||||||
|
/// </summary>
|
||||||
protected void GetProcessorInfo()
|
protected void GetProcessorInfo()
|
||||||
{
|
{
|
||||||
_firmware = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorFirmware.JoinNumber, JoinMap.ProcessorFirmware.AttributeName, eSigIoMask.InputSigOnly);
|
_firmware = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorFirmware.JoinNumber, JoinMap.ProcessorFirmware.AttributeName, eSigIoMask.InputSigOnly);
|
||||||
@@ -499,7 +646,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
{
|
{
|
||||||
var join = JoinMap.ProgramNameStart.JoinNumber + i;
|
var join = JoinMap.ProgramNameStart.JoinNumber + i;
|
||||||
var progNum = i + 1;
|
var progNum = i + 1;
|
||||||
_program[i] = FusionRoom.CreateOffsetStringSig((uint) join,
|
_program[i] = FusionRoom.CreateOffsetStringSig((uint)join,
|
||||||
string.Format("{0} {1}", JoinMap.ProgramNameStart.AttributeName, progNum), eSigIoMask.InputSigOnly);
|
string.Format("{0} {1}", JoinMap.ProgramNameStart.AttributeName, progNum), eSigIoMask.InputSigOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,6 +654,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
_firmware.InputSig.StringValue = InitialParametersClass.FirmwareVersion;
|
_firmware.InputSig.StringValue = InitialParametersClass.FirmwareVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GetCustomProperties method
|
||||||
|
/// </summary>
|
||||||
protected void GetCustomProperties()
|
protected void GetCustomProperties()
|
||||||
{
|
{
|
||||||
if (FusionRoom.IsOnline)
|
if (FusionRoom.IsOnline)
|
||||||
@@ -524,11 +674,16 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
// TODO: Get IP and Project Name from TP
|
// TODO: Get IP and Project Name from TP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FusionRoom_OnlineStatusChange method
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="currentDevice"></param>
|
||||||
|
/// <param name="args"></param>
|
||||||
protected void FusionRoom_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
|
protected void FusionRoom_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.DeviceOnLine)
|
if (args.DeviceOnLine)
|
||||||
{
|
{
|
||||||
CrestronInvoke.BeginInvoke( (o) =>
|
CrestronInvoke.BeginInvoke((o) =>
|
||||||
{
|
{
|
||||||
CrestronEnvironment.Sleep(200);
|
CrestronEnvironment.Sleep(200);
|
||||||
|
|
||||||
@@ -676,7 +831,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
var extendTime = _currentMeeting.dtEnd - DateTime.Now;
|
var extendTime = _currentMeeting.dtEnd - DateTime.Now;
|
||||||
var extendMinutesRaw = extendTime.TotalMinutes;
|
var extendMinutesRaw = extendTime.TotalMinutes;
|
||||||
|
|
||||||
extendMinutes += (int) Math.Round(extendMinutesRaw);
|
extendMinutes += (int)Math.Round(extendMinutesRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -784,11 +939,11 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
var parameters = actionResponse["Parameters"];
|
var parameters = actionResponse["Parameters"];
|
||||||
|
|
||||||
foreach (var isRegistered in from XmlElement parameter in parameters
|
foreach (var isRegistered in from XmlElement parameter in parameters
|
||||||
where parameter.HasAttributes
|
where parameter.HasAttributes
|
||||||
select parameter.Attributes
|
select parameter.Attributes
|
||||||
into attributes
|
into attributes
|
||||||
where attributes["ID"].Value == "Registered"
|
where attributes["ID"].Value == "Registered"
|
||||||
select Int32.Parse(attributes["Value"].Value))
|
select Int32.Parse(attributes["Value"].Value))
|
||||||
{
|
{
|
||||||
switch (isRegistered)
|
switch (isRegistered)
|
||||||
{
|
{
|
||||||
@@ -845,9 +1000,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
Debug.LogMessage(LogEventLevel.Debug, this, "DateTime from Fusion Server: {0}", currentTime);
|
Debug.LogMessage(LogEventLevel.Debug, this, "DateTime from Fusion Server: {0}", currentTime);
|
||||||
|
|
||||||
// Parse time and date from response and insert values
|
// Parse time and date from response and insert values
|
||||||
CrestronEnvironment.SetTimeAndDate((ushort) currentTime.Hour, (ushort) currentTime.Minute,
|
CrestronEnvironment.SetTimeAndDate((ushort)currentTime.Hour, (ushort)currentTime.Minute,
|
||||||
(ushort) currentTime.Second, (ushort) currentTime.Month, (ushort) currentTime.Day,
|
(ushort)currentTime.Second, (ushort)currentTime.Month, (ushort)currentTime.Day,
|
||||||
(ushort) currentTime.Year);
|
(ushort)currentTime.Year);
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "Processor time set to {0}", CrestronEnvironment.GetLocalTime());
|
Debug.LogMessage(LogEventLevel.Debug, this, "Processor time set to {0}", CrestronEnvironment.GetLocalTime());
|
||||||
}
|
}
|
||||||
@@ -1065,6 +1220,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SetUpSources method
|
||||||
|
/// </summary>
|
||||||
protected virtual void SetUpSources()
|
protected virtual void SetUpSources()
|
||||||
{
|
{
|
||||||
// Sources
|
// Sources
|
||||||
@@ -1074,10 +1232,10 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
// NEW PROCESS:
|
// NEW PROCESS:
|
||||||
// Make these lists and insert the fusion attributes by iterating these
|
// Make these lists and insert the fusion attributes by iterating these
|
||||||
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
|
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
|
||||||
uint i = 1;
|
uint i = 0;
|
||||||
foreach (var kvp in setTopBoxes)
|
foreach (var kvp in setTopBoxes)
|
||||||
{
|
{
|
||||||
TryAddRouteActionSigs(JoinMap.Display1SetTopBoxSourceStart.AttributeName + " " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
TryAddRouteActionSigs(JoinMap.Display1SetTopBoxSourceStart.AttributeName + " " + (i + 1), JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||||
i++;
|
i++;
|
||||||
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
|
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
|
||||||
{
|
{
|
||||||
@@ -1086,10 +1244,10 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
|
|
||||||
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
|
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
|
||||||
i = 1;
|
i = 0;
|
||||||
foreach (var kvp in discPlayers)
|
foreach (var kvp in discPlayers)
|
||||||
{
|
{
|
||||||
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + (i + 1), JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||||
i++;
|
i++;
|
||||||
if (i > JoinMap.Display1DiscPlayerSourceStart.JoinSpan) // We only have five spots
|
if (i > JoinMap.Display1DiscPlayerSourceStart.JoinSpan) // We only have five spots
|
||||||
{
|
{
|
||||||
@@ -1098,10 +1256,10 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
|
|
||||||
var laptops = dict.Where(d => d.Value.SourceDevice is IRoutingSource);
|
var laptops = dict.Where(d => d.Value.SourceDevice is IRoutingSource);
|
||||||
i = 1;
|
i = 0;
|
||||||
foreach (var kvp in laptops)
|
foreach (var kvp in laptops)
|
||||||
{
|
{
|
||||||
TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + (i + 1), JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||||
i++;
|
i++;
|
||||||
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
|
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
|
||||||
{
|
{
|
||||||
@@ -1111,7 +1269,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
foreach (var usageDevice in dict.Select(kvp => kvp.Value.SourceDevice).OfType<IUsageTracking>())
|
foreach (var usageDevice in dict.Select(kvp => kvp.Value.SourceDevice).OfType<IUsageTracking>())
|
||||||
{
|
{
|
||||||
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device) {UsageIsTracked = true};
|
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device) { UsageIsTracked = true };
|
||||||
usageDevice.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
usageDevice.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1157,17 +1315,31 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
Debug.LogMessage(LogEventLevel.Debug, this, "Device usage string: {0}", deviceUsage);
|
Debug.LogMessage(LogEventLevel.Debug, this, "Device usage string: {0}", deviceUsage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to add route action sigs for a source
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="attrName"></param>
|
||||||
|
/// <param name="attrNum"></param>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
/// <param name="pSrc"></param>
|
||||||
protected void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc)
|
protected void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Creating attribute '{0}' with join {1} for source {2}",
|
this.LogVerbose("Creating attribute '{0}' with join {1} for source {2}",
|
||||||
attrName, attrNum, pSrc.Key);
|
attrName, attrNum, pSrc.Key);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig);
|
var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig);
|
||||||
// Need feedback when this source is selected
|
// Need feedback when this source is selected
|
||||||
// Event handler, added below, will compare source changes with this sig dict
|
// Event handler, added below, will compare source changes with this sig dict
|
||||||
_sourceToFeedbackSigs.Add(pSrc, sigD.InputSig);
|
if (!_sourceToFeedbackSigs.ContainsKey(pSrc))
|
||||||
|
{
|
||||||
|
_sourceToFeedbackSigs.Add(pSrc, sigD.InputSig);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.LogWarning("Source '{0}' already has a feedback sig mapped. Overwriting.", pSrc.Key);
|
||||||
|
_sourceToFeedbackSigs[pSrc] = sigD.InputSig;
|
||||||
|
}
|
||||||
|
|
||||||
// And respond to selection in Fusion
|
// And respond to selection in Fusion
|
||||||
sigD.OutputSig.SetSigFalseAction(() =>
|
sigD.OutputSig.SetSigFalseAction(() =>
|
||||||
@@ -1180,14 +1352,12 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING",
|
this.LogVerbose("Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING",
|
||||||
attrNum, attrName, pSrc.Key);
|
attrNum, attrName, pSrc.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
private void SetUpCommunitcationMonitors()
|
private void SetUpCommunitcationMonitors()
|
||||||
{
|
{
|
||||||
uint displayNum = 0;
|
uint displayNum = 0;
|
||||||
@@ -1274,6 +1444,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
if (attrName != null)
|
if (attrName != null)
|
||||||
{
|
{
|
||||||
|
this.LogDebug("Linking communication monitor for device '{0}' to Fusion attribute '{1}' at join {2}",
|
||||||
|
dev.Key, attrName, attrNum);
|
||||||
// Link comm status to sig and update
|
// Link comm status to sig and update
|
||||||
var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly);
|
var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly);
|
||||||
var smd = dev as ICommunicationMonitor;
|
var smd = dev as ICommunicationMonitor;
|
||||||
@@ -1285,6 +1457,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SetUpDisplay method
|
||||||
|
/// </summary>
|
||||||
protected virtual void SetUpDisplay()
|
protected virtual void SetUpDisplay()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -1297,7 +1472,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
foreach (var display in displays.Cast<IDisplay>())
|
foreach (var display in displays.Cast<IDisplay>())
|
||||||
{
|
{
|
||||||
display.UsageTracker = new UsageTracking(display as Device) {UsageIsTracked = true};
|
display.UsageTracker = new UsageTracking(display as Device) { UsageIsTracked = true };
|
||||||
display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1410,7 +1585,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
|
|
||||||
// Power on
|
// Power on
|
||||||
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint) joinOffset, displayName + "Power On",
|
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On",
|
||||||
eSigIoMask.InputOutputSig);
|
eSigIoMask.InputOutputSig);
|
||||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b =>
|
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b =>
|
||||||
{
|
{
|
||||||
@@ -1421,7 +1596,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Power Off
|
// Power Off
|
||||||
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 1, displayName + "Power Off",
|
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off",
|
||||||
eSigIoMask.InputOutputSig);
|
eSigIoMask.InputOutputSig);
|
||||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b =>
|
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b =>
|
||||||
{
|
{
|
||||||
@@ -1439,7 +1614,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Current Source
|
// Current Source
|
||||||
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 8,
|
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8,
|
||||||
displayName + "Source None", eSigIoMask.InputOutputSig);
|
displayName + "Source None", eSigIoMask.InputOutputSig);
|
||||||
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b =>
|
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b =>
|
||||||
{
|
{
|
||||||
@@ -1507,7 +1682,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
//if (Room.OccupancyObj != null)
|
//if (Room.OccupancyObj != null)
|
||||||
//{
|
//{
|
||||||
|
|
||||||
var tempOccAsset = _guiDs.OccupancyAsset;
|
var tempOccAsset = _guids.OccupancyAsset;
|
||||||
|
|
||||||
if (tempOccAsset == null)
|
if (tempOccAsset == null)
|
||||||
{
|
{
|
||||||
@@ -1588,12 +1763,74 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event handler for Fusion state changes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="device"></param>
|
||||||
|
/// <param name="args"></param>
|
||||||
protected void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args)
|
protected void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args)
|
||||||
{
|
{
|
||||||
|
if (args.EventId == FusionEventIds.HelpMessageReceivedEventId)
|
||||||
|
{
|
||||||
|
this.LogInformation( "Help message received from Fusion for room '{0}'",
|
||||||
|
Room.Name);
|
||||||
|
|
||||||
|
this.LogDebug("Help message content: {0}", FusionRoom.Help.OutputSig.StringValue);
|
||||||
|
// Fire help request event
|
||||||
|
HelpRequestResponseFeedback.FireUpdate();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(FusionRoom.Help.OutputSig.StringValue))
|
||||||
|
{
|
||||||
|
switch (FusionRoom.Help.OutputSig.StringValue)
|
||||||
|
{
|
||||||
|
case "Please wait, a technician is on his / her way.":
|
||||||
|
// this.LogInformation("Please wait, a technician is on his / her way.",
|
||||||
|
// Room.Name);
|
||||||
|
|
||||||
|
_helpRequestStatus = eFusionHelpResponse.HelpOnTheWay;
|
||||||
|
break;
|
||||||
|
case "Please call the helpdesk.":
|
||||||
|
// this.LogInformation("Please call the helpdesk.");
|
||||||
|
// _helpRequestStatus = eFusionHelpResponse.CallHelpDesk;
|
||||||
|
break;
|
||||||
|
case "Please wait, I will reschedule your meeting to a different room.":
|
||||||
|
// this.LogInformation("Please wait, I will reschedule your meeting to a different room.",
|
||||||
|
// Room.Name);
|
||||||
|
|
||||||
|
_helpRequestStatus = eFusionHelpResponse.ReschedulingMeeting;
|
||||||
|
break;
|
||||||
|
case "I will be taking control of your system. Please be patient while I adjust the settings.":
|
||||||
|
// this.LogInformation("I will be taking control of your system. Please be patient while I adjust the settings.",
|
||||||
|
// Room.Name);
|
||||||
|
|
||||||
|
_helpRequestStatus = eFusionHelpResponse.TakingControl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// this.LogInformation("Unknown help request code received from Fusion for room '{0}'",
|
||||||
|
// Room.Name);
|
||||||
|
|
||||||
|
_helpRequestStatus = eFusionHelpResponse.None;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_helpRequestStatus = eFusionHelpResponse.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_helpRequestStatus == eFusionHelpResponse.None)
|
||||||
|
{
|
||||||
|
_helpRequestSent = false;
|
||||||
|
HelpRequestSentFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
HelpRequestStatusFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// The sig/UO method: Need separate handlers for fixed and user sigs, all flavors,
|
// The sig/UO method: Need separate handlers for fixed and user sigs, all flavors,
|
||||||
// even though they all contain sigs.
|
// even though they all contain sigs.
|
||||||
|
|
||||||
|
|
||||||
BoolOutputSig outSig;
|
BoolOutputSig outSig;
|
||||||
if (args.UserConfiguredSigDetail is BooleanSigDataFixedName sigData)
|
if (args.UserConfiguredSigDetail is BooleanSigDataFixedName sigData)
|
||||||
{
|
{
|
||||||
@@ -1632,9 +1869,69 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
(outSig.UserObject as Action<string>).Invoke(outSig.StringValue);
|
(outSig.UserObject as Action<string>).Invoke(outSig.StringValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void SendHelpRequest()
|
||||||
|
{
|
||||||
|
|
||||||
|
var now = DateTime.Now;
|
||||||
|
|
||||||
|
var breakString = _config.UseHtmlFormatForHelpRequests ? "<BR>" : "\r\n";
|
||||||
|
|
||||||
|
var date = now.ToString("MMMM dd, yyyy");
|
||||||
|
var time = now.ToString("hh:mm tt");
|
||||||
|
if (_config.Use24HourTimeFormat)
|
||||||
|
{
|
||||||
|
time = now.ToString("HH:mm");
|
||||||
|
}
|
||||||
|
|
||||||
|
var requestString = $"HR00: {breakString} Assistance has been requested from room {Room.Name}{breakString}on {date} at {time}";
|
||||||
|
|
||||||
|
FusionRoom.Help.InputSig.StringValue = requestString;
|
||||||
|
|
||||||
|
this.LogInformation("Help request sent to Fusion from room '{0}'", Room.Name);
|
||||||
|
this.LogDebug("Help request content: {0}", FusionRoom.Help.InputSig.StringValue);
|
||||||
|
|
||||||
|
_helpRequestSent = true;
|
||||||
|
HelpRequestSentFeedback.FireUpdate();
|
||||||
|
|
||||||
|
_helpRequestStatus = eFusionHelpResponse.HelpRequested;
|
||||||
|
HelpRequestStatusFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void CancelHelpRequest()
|
||||||
|
{
|
||||||
|
if (_helpRequestSent)
|
||||||
|
{
|
||||||
|
FusionRoom.Help.InputSig.StringValue = "";
|
||||||
|
_helpRequestSent = false;
|
||||||
|
HelpRequestSentFeedback.FireUpdate();
|
||||||
|
_helpRequestStatus = eFusionHelpResponse.None;
|
||||||
|
HelpRequestStatusFeedback.FireUpdate();
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, this, "Help request cancelled in Fusion for room '{0}'", Room.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void ToggleHelpRequest()
|
||||||
|
{
|
||||||
|
if (_helpRequestSent)
|
||||||
|
{
|
||||||
|
CancelHelpRequest();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendHelpRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extensions to enhance Fusion room, asset and signal creation.
|
||||||
|
/// </summary>
|
||||||
public static class FusionRoomExtensions
|
public static class FusionRoomExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1648,6 +1945,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
|
public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
|
||||||
{
|
{
|
||||||
|
Debug.LogDebug("Creating Offset Bool Sig: {0} at Join {1}", name, number);
|
||||||
|
|
||||||
if (number < 50)
|
if (number < 50)
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
|
throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
|
||||||
@@ -1668,6 +1967,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
|
public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
|
||||||
{
|
{
|
||||||
|
Debug.LogDebug("Creating Offset UShort Sig: {0} at Join {1}", name, number);
|
||||||
|
|
||||||
if (number < 50)
|
if (number < 50)
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
|
throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
|
||||||
@@ -1688,6 +1989,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
|
public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
|
||||||
{
|
{
|
||||||
|
Debug.LogDebug("Creating Offset String Sig: {0} at Join {1}", name, number);
|
||||||
|
|
||||||
if (number < 50)
|
if (number < 50)
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
|
throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
|
||||||
@@ -1803,6 +2106,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class RoomInformation
|
public class RoomInformation
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
public RoomInformation()
|
public RoomInformation()
|
||||||
{
|
{
|
||||||
FusionCustomProperties = new List<FusionCustomProperty>();
|
FusionCustomProperties = new List<FusionCustomProperty>();
|
||||||
@@ -1855,10 +2161,17 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class FusionCustomProperty
|
public class FusionCustomProperty
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
public FusionCustomProperty()
|
public FusionCustomProperty()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor with id
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
public FusionCustomProperty(string id)
|
public FusionCustomProperty(string id)
|
||||||
{
|
{
|
||||||
ID = id;
|
ID = id;
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Fusion;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Factory for creating IEssentialsRoomFusionController devices
|
||||||
|
/// </summary>
|
||||||
|
public class IEssentialsRoomFusionControllerFactory : EssentialsDeviceFactory<IEssentialsRoomFusionController>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
|
public IEssentialsRoomFusionControllerFactory()
|
||||||
|
{
|
||||||
|
TypeNames = new List<string>() { "fusionRoom" };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Builds the device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dc"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
|
||||||
|
{
|
||||||
|
Debug.LogDebug("Factory Attempting to create new IEssentialsRoomFusionController Device");
|
||||||
|
|
||||||
|
|
||||||
|
var properties = dc.Properties.ToObject<IEssentialsRoomFusionControllerPropertiesConfig>();
|
||||||
|
|
||||||
|
return new IEssentialsRoomFusionController(dc.Key, dc.Name, properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Config properties for an IEssentialsRoomFusionController device
|
||||||
|
/// </summary>
|
||||||
|
public class IEssentialsRoomFusionControllerPropertiesConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the IP ID of the Fusion Room Controller
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("ipId")]
|
||||||
|
public string IpId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the IP ID as a UInt16
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public uint IpIdInt
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Try to parse the IpId string to UInt16 as hex
|
||||||
|
if (ushort.TryParse(IpId, System.Globalization.NumberStyles.HexNumber, null, out ushort result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning( "Failed to parse IpId '{0}' as UInt16", IpId);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the join map key
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("joinMapKey")]
|
||||||
|
public string JoinMapKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the room key associated with this Fusion Room Controller
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("roomKey")]
|
||||||
|
public string RoomKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets whether to use HTML format for help requests
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("useHtmlFormatForHelpRequests")]
|
||||||
|
public bool UseHtmlFormatForHelpRequests { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets whether to use 24-hour time format
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("use24HourTimeFormat")]
|
||||||
|
public bool Use24HourTimeFormat { get; set; } = false;
|
||||||
|
}
|
||||||
44
src/PepperDash.Essentials.Core/Fusion/IFusionHelpRequest.cs
Normal file
44
src/PepperDash.Essentials.Core/Fusion/IFusionHelpRequest.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Fusion
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents Fusion Help Request functionality
|
||||||
|
/// </summary>
|
||||||
|
public interface IFusionHelpRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback containing the response to a help request
|
||||||
|
/// </summary>
|
||||||
|
StringFeedback HelpRequestResponseFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether a help request has been sent
|
||||||
|
/// </summary>
|
||||||
|
BoolFeedback HelpRequestSentFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback containing the current status of the help request
|
||||||
|
/// </summary>
|
||||||
|
StringFeedback HelpRequestStatusFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a help request
|
||||||
|
/// </summary>
|
||||||
|
void SendHelpRequest();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the current help request status
|
||||||
|
/// </summary>
|
||||||
|
void CancelHelpRequest();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles between sending and cancelling a help request
|
||||||
|
/// </summary>
|
||||||
|
void ToggleHelpRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/PepperDash.Essentials.Core/Fusion/eFusionHelpResponse.cs
Normal file
37
src/PepperDash.Essentials.Core/Fusion/eFusionHelpResponse.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Fusion
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enumeration of possible Fusion Help Responses based on the standard responses from Fusion
|
||||||
|
/// </summary>
|
||||||
|
public enum eFusionHelpResponse
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No help response
|
||||||
|
/// </summary>
|
||||||
|
None,
|
||||||
|
/// <summary>
|
||||||
|
/// Help has been requested
|
||||||
|
/// </summary>
|
||||||
|
HelpRequested,
|
||||||
|
/// <summary>
|
||||||
|
/// Help is on the way
|
||||||
|
/// </summary>
|
||||||
|
HelpOnTheWay,
|
||||||
|
/// <summary>
|
||||||
|
/// Please call the helpdesk.
|
||||||
|
/// </summary>
|
||||||
|
CallHelpDesk,
|
||||||
|
/// <summary>
|
||||||
|
/// Rescheduling meeting.
|
||||||
|
/// </summary>
|
||||||
|
ReschedulingMeeting,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Technician taking control.
|
||||||
|
/// </summary>
|
||||||
|
TakingControl,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -49,7 +49,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IRoomOccupancy Room { get; private set; }
|
public IRoomOccupancy Room { get; private set; }
|
||||||
|
|
||||||
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom;
|
private Fusion.IEssentialsRoomFusionController FusionRoom;
|
||||||
|
|
||||||
public RoomOnToDefaultSourceWhenOccupied(DeviceConfig config) :
|
public RoomOnToDefaultSourceWhenOccupied(DeviceConfig config) :
|
||||||
base (config)
|
base (config)
|
||||||
@@ -74,7 +74,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
var fusionRoomKey = PropertiesConfig.RoomKey + "-fusion";
|
var fusionRoomKey = PropertiesConfig.RoomKey + "-fusion";
|
||||||
|
|
||||||
FusionRoom = DeviceManager.GetDeviceForKey(fusionRoomKey) as Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase;
|
FusionRoom = DeviceManager.GetDeviceForKey(fusionRoomKey) as Core.Fusion.IEssentialsRoomFusionController;
|
||||||
|
|
||||||
if (FusionRoom == null)
|
if (FusionRoom == null)
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to get Fusion Room from Device Manager with key: {0}", fusionRoomKey);
|
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to get Fusion Room from Device Manager with key: {0}", fusionRoomKey);
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
Debug.LogMessage(LogEventLevel.Information, this, "Timeout Minutes from Config is: {0}", timeoutMinutes);
|
Debug.LogMessage(LogEventLevel.Information, this, "Timeout Minutes from Config is: {0}", timeoutMinutes);
|
||||||
|
|
||||||
// If status provider is fusion, set flag to remote
|
// If status provider is fusion, set flag to remote
|
||||||
if (statusProvider is Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
|
if (statusProvider is Core.Fusion.IEssentialsRoomFusionController)
|
||||||
OccupancyStatusProviderIsRemote = true;
|
OccupancyStatusProviderIsRemote = true;
|
||||||
|
|
||||||
if(timeoutMinutes > 0)
|
if(timeoutMinutes > 0)
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ namespace PepperDash.Essentials.Core.Routing
|
|||||||
/// <param name="inputPort">The currently selected input port on the destination device.</param>
|
/// <param name="inputPort">The currently selected input port on the destination device.</param>
|
||||||
private void UpdateDestination(IRoutingSinkWithSwitching destination, RoutingInputPort inputPort)
|
private void UpdateDestination(IRoutingSinkWithSwitching destination, RoutingInputPort inputPort)
|
||||||
{
|
{
|
||||||
// Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Updating destination {destination} with inputPort {inputPort}", this,destination?.Key, inputPort?.Key);
|
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Updating destination {destination} with inputPort {inputPort}", this, destination?.Key, inputPort?.Key);
|
||||||
|
|
||||||
if(inputPort == null)
|
if(inputPort == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
using PepperDash.Essentials.Core;
|
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
|
||||||
using PepperDash.Core;
|
|
||||||
using Crestron.SimplSharpPro.UI;
|
|
||||||
using Crestron.SimplSharp.CrestronIO;
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
using Crestron.SimplSharpPro;
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Core.Logging;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.UI
|
namespace PepperDash.Essentials.Core.UI
|
||||||
{
|
{
|
||||||
public abstract class TouchpanelBase: EssentialsDevice, IHasBasicTriListWithSmartObject
|
/// <summary>
|
||||||
|
/// Base class for Touchpanel devices
|
||||||
|
/// </summary>
|
||||||
|
public abstract class TouchpanelBase : EssentialsDevice, IHasBasicTriListWithSmartObject
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the configuration for the Crestron touchpanel.
|
||||||
|
/// </summary>
|
||||||
protected CrestronTouchpanelPropertiesConfig _config;
|
protected CrestronTouchpanelPropertiesConfig _config;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Panel
|
/// Gets or sets the Panel
|
||||||
@@ -28,11 +30,10 @@ namespace PepperDash.Essentials.Core.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">Essentials Device Key</param>
|
/// <param name="key">Essentials Device Key</param>
|
||||||
/// <param name="name">Essentials Device Name</param>
|
/// <param name="name">Essentials Device Name</param>
|
||||||
/// <param name="type">Touchpanel Type to build</param>
|
/// <param name="panel">Crestron Touchpanel Device</param>
|
||||||
/// <param name="config">Touchpanel Configuration</param>
|
/// <param name="config">Touchpanel Configuration</param>
|
||||||
/// <param name="id">IP-ID to use for touch panel</param>
|
|
||||||
protected TouchpanelBase(string key, string name, BasicTriListWithSmartObject panel, CrestronTouchpanelPropertiesConfig config)
|
protected TouchpanelBase(string key, string name, BasicTriListWithSmartObject panel, CrestronTouchpanelPropertiesConfig config)
|
||||||
:base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (panel == null)
|
if (panel == null)
|
||||||
@@ -57,21 +58,19 @@ namespace PepperDash.Essentials.Core.UI
|
|||||||
|
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
||||||
AddPreActivationAction(() => {
|
AddPreActivationAction(() =>
|
||||||
if (Panel.Register() != eDeviceRegistrationUnRegistrationResponse.Success)
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "WARNING: Registration failed. Continuing, but panel may not function: {0}", Panel.RegistrationFailureReason);
|
|
||||||
|
|
||||||
// Give up cleanly if SGD is not present.
|
// Give up cleanly if SGD is not present.
|
||||||
var sgdName = Global.FilePathPrefix + "sgd" + Global.DirectorySeparator + _config.SgdFile;
|
var sgdName = Global.FilePathPrefix + "sgd" + Global.DirectorySeparator + _config.SgdFile;
|
||||||
if (!File.Exists(sgdName))
|
if (!File.Exists(sgdName))
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Smart object file '{0}' not present in User folder. Looking for embedded file", sgdName);
|
this.LogInformation("Smart object file '{0}' not present in User folder. Looking for embedded file", sgdName);
|
||||||
|
|
||||||
sgdName = Global.ApplicationDirectoryPathPrefix + Global.DirectorySeparator + "SGD" + Global.DirectorySeparator + _config.SgdFile;
|
sgdName = Global.ApplicationDirectoryPathPrefix + Global.DirectorySeparator + "SGD" + Global.DirectorySeparator + _config.SgdFile;
|
||||||
|
|
||||||
if (!File.Exists(sgdName))
|
if (!File.Exists(sgdName))
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Unable to find SGD file '{0}' in User sgd or application SGD folder. Exiting touchpanel load.", sgdName);
|
this.LogWarning("Unable to find SGD file '{0}' in User sgd or application SGD folder. Exiting touchpanel load.", sgdName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,12 +81,11 @@ namespace PepperDash.Essentials.Core.UI
|
|||||||
AddPostActivationAction(() =>
|
AddPostActivationAction(() =>
|
||||||
{
|
{
|
||||||
// Check for IEssentialsRoomCombiner in DeviceManager and if found, subscribe to its event
|
// Check for IEssentialsRoomCombiner in DeviceManager and if found, subscribe to its event
|
||||||
var roomCombiner = DeviceManager.AllDevices.FirstOrDefault((d) => d is IEssentialsRoomCombiner) as IEssentialsRoomCombiner;
|
|
||||||
|
|
||||||
if (roomCombiner != null)
|
if (DeviceManager.AllDevices.FirstOrDefault((d) => d is IEssentialsRoomCombiner) is IEssentialsRoomCombiner roomCombiner)
|
||||||
{
|
{
|
||||||
// Subscribe to the even
|
// Subscribe to the even
|
||||||
roomCombiner.RoomCombinationScenarioChanged += new EventHandler<EventArgs>(roomCombiner_RoomCombinationScenarioChanged);
|
roomCombiner.RoomCombinationScenarioChanged += new EventHandler<EventArgs>(RoomCombiner_RoomCombinationScenarioChanged);
|
||||||
|
|
||||||
// Connect to the initial roomKey
|
// Connect to the initial roomKey
|
||||||
if (roomCombiner.CurrentScenario != null)
|
if (roomCombiner.CurrentScenario != null)
|
||||||
@@ -106,6 +104,11 @@ namespace PepperDash.Essentials.Core.UI
|
|||||||
// No room combiner, use the default key
|
// No room combiner, use the default key
|
||||||
SetupPanelDrivers(_config.DefaultRoomKey);
|
SetupPanelDrivers(_config.DefaultRoomKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var panelRegistrationResponse = Panel.Register();
|
||||||
|
|
||||||
|
if (panelRegistrationResponse != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||||
|
this.LogInformation("WARNING: Registration failed. Continuing, but panel may not function: {0}", Panel.RegistrationFailureReason);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +118,6 @@ namespace PepperDash.Essentials.Core.UI
|
|||||||
/// <param name="roomKey">Room Key for this panel</param>
|
/// <param name="roomKey">Room Key for this panel</param>
|
||||||
protected abstract void SetupPanelDrivers(string roomKey);
|
protected abstract void SetupPanelDrivers(string roomKey);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event handler for System Extender Events
|
/// Event handler for System Extender Events
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -129,7 +131,7 @@ namespace PepperDash.Essentials.Core.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
protected virtual void roomCombiner_RoomCombinationScenarioChanged(object sender, EventArgs e)
|
protected virtual void RoomCombiner_RoomCombinationScenarioChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var roomCombiner = sender as IEssentialsRoomCombiner;
|
var roomCombiner = sender as IEssentialsRoomCombiner;
|
||||||
|
|
||||||
@@ -156,23 +158,23 @@ namespace PepperDash.Essentials.Core.UI
|
|||||||
SetupPanelDrivers(newRoomKey);
|
SetupPanelDrivers(newRoomKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Panel_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
|
private void Panel_SigChange(object currentDevice, SigEventArgs args)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Sig change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
this.LogVerbose("Sig change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||||
var uo = args.Sig.UserObject;
|
var uo = args.Sig.UserObject;
|
||||||
if (uo is Action<bool>)
|
if (uo is Action<bool>)
|
||||||
(uo as Action<bool>)(args.Sig.BoolValue);
|
(uo as Action<bool>)(args.Sig.BoolValue);
|
||||||
else if (uo is Action<ushort>)
|
else if (uo is Action<ushort>)
|
||||||
(uo as Action<ushort>)(args.Sig.UShortValue);
|
(uo as Action<ushort>)(args.Sig.UShortValue);
|
||||||
else if (uo is Action<string>)
|
else if (uo is Action<string>)
|
||||||
(uo as Action<string>)(args.Sig.StringValue);
|
(uo as Action<string>)(args.Sig.StringValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Tsw_ButtonStateChange(GenericBase device, ButtonEventArgs args)
|
private void Tsw_ButtonStateChange(GenericBase device, ButtonEventArgs args)
|
||||||
{
|
{
|
||||||
var uo = args.Button.UserObject;
|
var uo = args.Button.UserObject;
|
||||||
if(uo is Action<bool>)
|
if (uo is Action<bool>)
|
||||||
(uo as Action<bool>)(args.Button.State == eButtonState.Pressed);
|
(uo as Action<bool>)(args.Button.State == eButtonState.Pressed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,9 +6,9 @@ using PepperDash.Core.Web.RequestHandlers;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a SetDeviceStreamDebugRequestHandler
|
/// Represents a SetDeviceStreamDebugRequestHandler
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SetDeviceStreamDebugRequestHandler : WebApiBaseRequestHandler
|
public class SetDeviceStreamDebugRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -122,23 +122,23 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(DeviceManager.GetDeviceForKey(body.DeviceKey) is IStreamDebugging device))
|
if (!(DeviceManager.GetDeviceForKey(body.DeviceKey) is IStreamDebugging device))
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = 404;
|
context.Response.StatusCode = 404;
|
||||||
context.Response.StatusDescription = "Not Found";
|
context.Response.StatusDescription = "Not Found";
|
||||||
context.Response.End();
|
context.Response.End();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
eStreamDebuggingSetting debugSetting;
|
eStreamDebuggingSetting debugSetting;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
debugSetting = (eStreamDebuggingSetting) Enum.Parse(typeof (eStreamDebuggingSetting), body.Setting, true);
|
debugSetting = (eStreamDebuggingSetting)Enum.Parse(typeof(eStreamDebuggingSetting), body.Setting, true);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(ex, "Exception handling set debug request");
|
Debug.LogMessage(ex, "Exception handling set debug request");
|
||||||
context.Response.StatusCode = 500;
|
context.Response.StatusCode = 500;
|
||||||
context.Response.StatusDescription = "Internal Server Error";
|
context.Response.StatusDescription = "Internal Server Error";
|
||||||
context.Response.End();
|
context.Response.End();
|
||||||
@@ -164,7 +164,7 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(ex, "Exception handling set debug request");
|
Debug.LogMessage(ex, "Exception handling set debug request");
|
||||||
context.Response.StatusCode = 500;
|
context.Response.StatusCode = 500;
|
||||||
context.Response.StatusDescription = "Internal Server Error";
|
context.Response.StatusDescription = "Internal Server Error";
|
||||||
context.Response.End();
|
context.Response.End();
|
||||||
@@ -198,21 +198,21 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
|||||||
public class SetDeviceStreamDebugConfig
|
public class SetDeviceStreamDebugConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("deviceKey", NullValueHandling = NullValueHandling.Include)]
|
[JsonProperty("deviceKey", NullValueHandling = NullValueHandling.Include)]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the DeviceKey
|
/// Gets or sets the DeviceKey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DeviceKey { get; set; }
|
public string DeviceKey { get; set; }
|
||||||
|
|
||||||
[JsonProperty("setting", NullValueHandling = NullValueHandling.Include)]
|
[JsonProperty("setting", NullValueHandling = NullValueHandling.Include)]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Setting
|
/// Gets or sets the Setting
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Setting { get; set; }
|
public string Setting { get; set; }
|
||||||
|
|
||||||
[JsonProperty("timeout")]
|
[JsonProperty("timeout")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Timeout
|
/// Gets or sets the Timeout
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Timeout { get; set; }
|
public int Timeout { get; set; }
|
||||||
|
|
||||||
public SetDeviceStreamDebugConfig()
|
public SetDeviceStreamDebugConfig()
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
@@ -17,39 +13,56 @@ namespace PepperDash.Essentials.Devices.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericAudioOut : EssentialsDevice, IRoutingSink
|
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; }
|
/// <summary>
|
||||||
public SourceListItem CurrentSourceInfo
|
/// Gets or sets the current source info key
|
||||||
{
|
/// </summary>
|
||||||
get
|
public string CurrentSourceInfoKey { get; set; }
|
||||||
{
|
/// <summary>
|
||||||
return _CurrentSourceInfo;
|
/// Gets or sets the current source info
|
||||||
}
|
/// </summary>
|
||||||
set
|
public SourceListItem CurrentSourceInfo
|
||||||
{
|
{
|
||||||
if (value == _CurrentSourceInfo) return;
|
get
|
||||||
|
{
|
||||||
|
return _CurrentSourceInfo;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
var handler = CurrentSourceChange;
|
var handler = CurrentSourceChange;
|
||||||
|
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
_CurrentSourceInfo = value;
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SourceListItem _CurrentSourceInfo;
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the AnyAudioIn
|
/// Gets or sets the AnyAudioIn
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RoutingInputPort AnyAudioIn { get; private set; }
|
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)
|
public GenericAudioOut(string key, string name)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
@@ -59,6 +72,9 @@ namespace PepperDash.Essentials.Devices.Common
|
|||||||
|
|
||||||
#region IRoutingInputs Members
|
#region IRoutingInputs Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the collection of input ports
|
||||||
|
/// </summary>
|
||||||
public RoutingPortCollection<RoutingInputPort> InputPorts
|
public RoutingPortCollection<RoutingInputPort> InputPorts
|
||||||
{
|
{
|
||||||
get { return new RoutingPortCollection<RoutingInputPort> { AnyAudioIn }; }
|
get { return new RoutingPortCollection<RoutingInputPort> { AnyAudioIn }; }
|
||||||
@@ -68,14 +84,23 @@ namespace PepperDash.Essentials.Devices.Common
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a GenericAudioOutWithVolume
|
/// Represents a GenericAudioOutWithVolume
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericAudioOutWithVolume : GenericAudioOut, IHasVolumeDevice
|
public class GenericAudioOutWithVolume : GenericAudioOut, IHasVolumeDevice
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the volume device key
|
||||||
|
/// </summary>
|
||||||
public string VolumeDeviceKey { get; private set; }
|
public string VolumeDeviceKey { get; private set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the volume zone
|
||||||
|
/// </summary>
|
||||||
public uint VolumeZone { get; private set; }
|
public uint VolumeZone { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the volume device
|
||||||
|
/// </summary>
|
||||||
public IBasicVolumeControls VolumeDevice
|
public IBasicVolumeControls VolumeDevice
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -103,24 +128,30 @@ namespace PepperDash.Essentials.Devices.Common
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GenericAudioOutWithVolumeFactory : EssentialsDeviceFactory<GenericAudioOutWithVolume>
|
/// <summary>
|
||||||
{
|
/// Factory for creating GenericAudioOutWithVolume devices
|
||||||
public GenericAudioOutWithVolumeFactory()
|
/// </summary>
|
||||||
{
|
public class GenericAudioOutWithVolumeFactory : EssentialsDeviceFactory<GenericAudioOutWithVolume>
|
||||||
TypeNames = new List<string>() { "genericaudiooutwithvolume" };
|
{
|
||||||
}
|
/// <summary>
|
||||||
|
/// Constructor for GenericAudioOutWithVolumeFactory
|
||||||
|
/// </summary>
|
||||||
|
public GenericAudioOutWithVolumeFactory()
|
||||||
|
{
|
||||||
|
TypeNames = new List<string>() { "genericaudiooutwithvolume" };
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// BuildDevice method
|
/// BuildDevice method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new GenericAudioOutWithVolumeFactory Device");
|
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new GenericAudioOutWithVolumeFactory Device");
|
||||||
var zone = dc.Properties.Value<uint>("zone");
|
var zone = dc.Properties.Value<uint>("zone");
|
||||||
return new GenericAudioOutWithVolume(dc.Key, dc.Name,
|
return new GenericAudioOutWithVolume(dc.Key, dc.Name,
|
||||||
dc.Properties.Value<string>("volumeDeviceKey"), zone);
|
dc.Properties.Value<string>("volumeDeviceKey"), zone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
using PepperDash.Core;
|
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Devices.Common.Codec;
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Abstract base class for audio codec devices
|
||||||
|
/// </summary>
|
||||||
public abstract class AudioCodecBase : EssentialsDevice, IHasDialer, IUsageTracking, IAudioCodecInfo
|
public abstract class AudioCodecBase : EssentialsDevice, IHasDialer, IUsageTracking, IAudioCodecInfo
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when call status changes
|
||||||
|
/// </summary>
|
||||||
public event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
|
public event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -52,6 +54,11 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public List<CodecActiveCallItem> ActiveCalls { get; set; }
|
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)
|
public AudioCodecBase(string key, string name)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
@@ -70,11 +77,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Handles call status change events
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="previousStatus"></param>
|
/// <param name="item">The call item that changed status</param>
|
||||||
/// <param name="newStatus"></param>
|
|
||||||
/// <param name="item"></param>
|
|
||||||
protected void OnCallStatusChange(CodecActiveCallItem item)
|
protected void OnCallStatusChange(CodecActiveCallItem item)
|
||||||
{
|
{
|
||||||
var handler = CallStatusChange;
|
var handler = CallStatusChange;
|
||||||
@@ -92,16 +97,22 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
|||||||
|
|
||||||
#region IHasDialer Members
|
#region IHasDialer Members
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public abstract void Dial(string number);
|
public abstract void Dial(string number);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public abstract void EndCall(CodecActiveCallItem activeCall);
|
public abstract void EndCall(CodecActiveCallItem activeCall);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public abstract void EndAllCalls();
|
public abstract void EndAllCalls();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public abstract void AcceptCall(CodecActiveCallItem item);
|
public abstract void AcceptCall(CodecActiveCallItem item);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public abstract void RejectCall(CodecActiveCallItem item);
|
public abstract void RejectCall(CodecActiveCallItem item);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public abstract void SendDtmf(string digit);
|
public abstract void SendDtmf(string digit);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
using System;
|
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements a common set of data about a codec
|
/// Implements a common set of data about a codec
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IAudioCodecInfo
|
public interface IAudioCodecInfo
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the codec information
|
||||||
|
/// </summary>
|
||||||
AudioCodecInfo CodecInfo { get; }
|
AudioCodecInfo CodecInfo { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,6 +16,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class AudioCodecInfo
|
public abstract class AudioCodecInfo
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the phone number
|
||||||
|
/// </summary>
|
||||||
public abstract string PhoneNumber { get; set; }
|
public abstract string PhoneNumber { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,17 @@
|
|||||||
using System;
|
using PepperDash.Essentials.Core;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
using PepperDash.Essentials.Core;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For rooms that have audio codec
|
/// For rooms that have audio codec
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasAudioCodec:IHasInCallFeedback
|
public interface IHasAudioCodec : IHasInCallFeedback
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the audio codec device
|
||||||
|
/// </summary>
|
||||||
AudioCodecBase AudioCodec { get; }
|
AudioCodecBase AudioCodec { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Make this more specific
|
|
||||||
/// </summary>
|
|
||||||
//List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem> ActiveCalls { get; }
|
//List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem> ActiveCalls { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
@@ -17,6 +13,12 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MockAC : AudioCodecBase
|
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)
|
public MockAC(string key, string name, MockAcPropertiesConfig props)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
@@ -109,13 +111,10 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
|||||||
Debug.LogMessage(LogEventLevel.Debug, this, "BEEP BOOP SendDTMF: {0}", s);
|
Debug.LogMessage(LogEventLevel.Debug, this, "BEEP BOOP SendDTMF: {0}", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="url"></param>
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TestIncomingAudioCall method
|
/// TestIncomingAudioCall method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="number">Phone number to call from</param>
|
||||||
public void TestIncomingAudioCall(string number)
|
public void TestIncomingAudioCall(string number)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "TestIncomingAudioCall from {0}", number);
|
Debug.LogMessage(LogEventLevel.Debug, this, "TestIncomingAudioCall from {0}", number);
|
||||||
@@ -133,6 +132,7 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
|||||||
{
|
{
|
||||||
string _phoneNumber;
|
string _phoneNumber;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public override string PhoneNumber
|
public override string PhoneNumber
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -151,6 +151,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MockACFactory : EssentialsDeviceFactory<MockAC>
|
public class MockACFactory : EssentialsDeviceFactory<MockAC>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for MockACFactory
|
||||||
|
/// </summary>
|
||||||
public MockACFactory()
|
public MockACFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string>() { "mockac" };
|
TypeNames = new List<string>() { "mockac" };
|
||||||
|
|||||||
@@ -1,12 +1,4 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||||
{
|
{
|
||||||
@@ -15,10 +7,10 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MockAcPropertiesConfig
|
public class MockAcPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("phoneNumber")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the PhoneNumber
|
/// Gets or sets the PhoneNumber
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("phoneNumber")]
|
||||||
public string PhoneNumber { get; set; }
|
public string PhoneNumber { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,20 +3,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
using System.Reflection;
|
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Devices;
|
|
||||||
using PepperDash.Essentials.Core.Config;
|
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Core.Devices;
|
||||||
using PepperDash.Essentials.Core.Presets;
|
using PepperDash.Essentials.Core.Presets;
|
||||||
using PepperDash.Essentials.Devices.Common.Codec;
|
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||||
@@ -26,31 +20,52 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum eCameraCapabilities
|
public enum eCameraCapabilities
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No camera capabilities
|
||||||
|
/// </summary>
|
||||||
None = 0,
|
None = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Camera supports pan movement
|
||||||
|
/// </summary>
|
||||||
Pan = 1,
|
Pan = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// Camera supports tilt movement
|
||||||
|
/// </summary>
|
||||||
Tilt = 2,
|
Tilt = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// Camera supports zoom functionality
|
||||||
|
/// </summary>
|
||||||
Zoom = 4,
|
Zoom = 4,
|
||||||
|
/// <summary>
|
||||||
|
/// Camera supports focus adjustment
|
||||||
|
/// </summary>
|
||||||
Focus = 8
|
Focus = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Abstract base class for camera devices that provides common camera functionality and capabilities
|
||||||
|
/// </summary>
|
||||||
public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs
|
public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs
|
||||||
{
|
{
|
||||||
[JsonProperty("controlMode", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the ControlMode
|
/// Gets or sets the ControlMode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("controlMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public eCameraControlMode ControlMode { get; protected set; }
|
public eCameraControlMode ControlMode { get; protected set; }
|
||||||
|
|
||||||
#region IRoutingOutputs Members
|
#region IRoutingOutputs Members
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the OutputPorts
|
/// Gets or sets the OutputPorts
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; protected set; }
|
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; protected set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this camera supports pan movement
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public bool CanPan
|
public bool CanPan
|
||||||
{
|
{
|
||||||
@@ -59,6 +74,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
return (Capabilities & eCameraCapabilities.Pan) == eCameraCapabilities.Pan;
|
return (Capabilities & eCameraCapabilities.Pan) == eCameraCapabilities.Pan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this camera supports tilt movement
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public bool CanTilt
|
public bool CanTilt
|
||||||
{
|
{
|
||||||
@@ -67,6 +86,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
return (Capabilities & eCameraCapabilities.Tilt) == eCameraCapabilities.Tilt;
|
return (Capabilities & eCameraCapabilities.Tilt) == eCameraCapabilities.Tilt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this camera supports zoom functionality
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public bool CanZoom
|
public bool CanZoom
|
||||||
{
|
{
|
||||||
@@ -75,6 +98,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
return (Capabilities & eCameraCapabilities.Zoom) == eCameraCapabilities.Zoom;
|
return (Capabilities & eCameraCapabilities.Zoom) == eCameraCapabilities.Zoom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this camera supports focus adjustment
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public bool CanFocus
|
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 eCameraCapabilities Capabilities { get; set; }
|
||||||
|
|
||||||
protected CameraBase(DeviceConfig config) : base(config)
|
/// <summary>
|
||||||
{
|
/// Initializes a new instance of the CameraBase class with the specified device configuration
|
||||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
/// </summary>
|
||||||
|
/// <param name="config">The device configuration</param>
|
||||||
|
protected CameraBase(DeviceConfig config) : base(config)
|
||||||
|
{
|
||||||
|
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||||
|
|
||||||
ControlMode = eCameraControlMode.Manual;
|
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) :
|
protected CameraBase(string key, string name) :
|
||||||
this (new DeviceConfig{Name = name, Key = key})
|
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,
|
protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||||
EiscApiAdvanced bridge)
|
EiscApiAdvanced bridge)
|
||||||
{
|
{
|
||||||
@@ -240,13 +286,13 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
{
|
{
|
||||||
int tempNum = i;
|
int tempNum = i;
|
||||||
|
|
||||||
trilist.SetSigTrueAction((ushort) (joinMap.PresetRecallStart.JoinNumber + tempNum), () =>
|
trilist.SetSigTrueAction((ushort)(joinMap.PresetRecallStart.JoinNumber + tempNum), () =>
|
||||||
{
|
{
|
||||||
presetsCamera.PresetSelect(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);
|
presetsCamera.PresetStore(tempNum, label);
|
||||||
});
|
});
|
||||||
@@ -277,7 +323,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label);
|
trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -285,6 +331,13 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CameraPreset : PresetBase
|
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)
|
public CameraPreset(int id, string description, bool isDefined, bool isDefinable)
|
||||||
: base(id, description, isDefined, isDefinable)
|
: base(id, description, isDefined, isDefinable)
|
||||||
{
|
{
|
||||||
@@ -293,37 +346,37 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a CameraPropertiesConfig
|
/// Represents a CameraPropertiesConfig
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CameraPropertiesConfig
|
public class CameraPropertiesConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the CommunicationMonitorProperties
|
/// Gets or sets the CommunicationMonitorProperties
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
|
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Control
|
/// Gets or sets the Control
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ControlPropertiesConfig Control { get; set; }
|
public ControlPropertiesConfig Control { get; set; }
|
||||||
|
|
||||||
[JsonProperty("supportsAutoMode")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the SupportsAutoMode
|
/// Gets or sets the SupportsAutoMode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("supportsAutoMode")]
|
||||||
public bool SupportsAutoMode { get; set; }
|
public bool SupportsAutoMode { get; set; }
|
||||||
|
|
||||||
[JsonProperty("supportsOffMode")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the SupportsOffMode
|
/// Gets or sets the SupportsOffMode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("supportsOffMode")]
|
||||||
public bool SupportsOffMode { get; set; }
|
public bool SupportsOffMode { get; set; }
|
||||||
|
|
||||||
[JsonProperty("presets")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Presets
|
/// Gets or sets the Presets
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("presets")]
|
||||||
public List<CameraPreset> Presets { get; set; }
|
public List<CameraPreset> Presets { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,38 +3,33 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Devices.Common.Codec;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a CameraVisca
|
/// Represents a CameraVisca
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IHasPowerControlWithFeedback, IBridgeAdvanced, IHasCameraFocusControl, IHasAutoFocusMode
|
public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IHasPowerControlWithFeedback, IBridgeAdvanced, IHasCameraFocusControl, IHasAutoFocusMode
|
||||||
{
|
{
|
||||||
private readonly CameraViscaPropertiesConfig PropertiesConfig;
|
private readonly CameraViscaPropertiesConfig PropertiesConfig;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Communication
|
/// Gets or sets the Communication
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IBasicCommunication Communication { get; private set; }
|
public IBasicCommunication Communication { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the CommunicationMonitor
|
/// Gets or sets the CommunicationMonitor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to store the actions to parse inquiry responses as the inquiries are sent
|
/// 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)
|
/// Camera ID (Default 1)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte ID = 0x01;
|
public byte ID = 0x01;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Response ID used for VISCA communication
|
||||||
|
/// </summary>
|
||||||
public byte ResponseID;
|
public byte ResponseID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Slow speed value for pan movement
|
||||||
|
/// </summary>
|
||||||
|
public byte PanSpeedSlow = 0x10;
|
||||||
|
|
||||||
public byte PanSpeedSlow = 0x10;
|
/// <summary>
|
||||||
public byte TiltSpeedSlow = 0x10;
|
/// Slow speed value for tilt movement
|
||||||
|
/// </summary>
|
||||||
|
public byte TiltSpeedSlow = 0x10;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fast speed value for pan movement
|
||||||
|
/// </summary>
|
||||||
public byte PanSpeedFast = 0x13;
|
public byte PanSpeedFast = 0x13;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fast speed value for tilt movement
|
||||||
|
/// </summary>
|
||||||
public byte TiltSpeedFast = 0x13;
|
public byte TiltSpeedFast = 0x13;
|
||||||
|
|
||||||
// private bool IsMoving;
|
// private bool IsMoving;
|
||||||
private bool IsZooming;
|
private bool IsZooming;
|
||||||
|
|
||||||
bool _powerIsOn;
|
bool _powerIsOn;
|
||||||
public bool PowerIsOn
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether the camera power is on
|
||||||
|
/// </summary>
|
||||||
|
public bool PowerIsOn
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -87,12 +103,23 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
|
|
||||||
long FastSpeedHoldTimeMs = 2000;
|
long FastSpeedHoldTimeMs = 2000;
|
||||||
|
|
||||||
byte[] IncomingBuffer = new byte[] { };
|
byte[] IncomingBuffer = new byte[] { };
|
||||||
public BoolFeedback PowerIsOnFeedback { get; private set; }
|
|
||||||
|
|
||||||
|
/// <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) :
|
public CameraVisca(string key, string name, IBasicCommunication comm, CameraViscaPropertiesConfig props) :
|
||||||
base(key, name)
|
base(key, name)
|
||||||
{
|
{
|
||||||
InquiryResponseQueue = new CrestronQueue<Action<byte[]>>(15);
|
InquiryResponseQueue = new CrestronQueue<Action<byte[]>>(15);
|
||||||
|
|
||||||
Presets = props.Presets;
|
Presets = props.Presets;
|
||||||
@@ -121,19 +148,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
}
|
}
|
||||||
|
|
||||||
Communication.BytesReceived += new EventHandler<GenericCommMethodReceiveBytesArgs>(Communication_BytesReceived);
|
Communication.BytesReceived += new EventHandler<GenericCommMethodReceiveBytesArgs>(Communication_BytesReceived);
|
||||||
PowerIsOnFeedback = new BoolFeedback(() => { return PowerIsOn; });
|
PowerIsOnFeedback = new BoolFeedback("powerIsOn", () => { return PowerIsOn; });
|
||||||
CameraIsOffFeedback = new BoolFeedback(() => { return !PowerIsOn; });
|
CameraIsOffFeedback = new BoolFeedback("cameraIsOff", () => { return !PowerIsOn; });
|
||||||
|
|
||||||
if (props.CommunicationMonitorProperties != null)
|
if (props.CommunicationMonitorProperties != null)
|
||||||
{
|
{
|
||||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
|
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 20000, 120000, 300000, "\x81\x09\x04\x00\xFF");
|
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 20000, 120000, 300000, "\x81\x09\x04\x00\xFF");
|
||||||
}
|
}
|
||||||
DeviceManager.AddDevice(CommunicationMonitor);
|
DeviceManager.AddDevice(CommunicationMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -165,57 +192,57 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CustomActivate method
|
/// CustomActivate method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool CustomActivate()
|
public override bool CustomActivate()
|
||||||
{
|
{
|
||||||
Communication.Connect();
|
Communication.Connect();
|
||||||
|
|
||||||
|
|
||||||
CommunicationMonitor.StatusChange += (o, a) => { Debug.LogMessage(LogEventLevel.Verbose, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
|
CommunicationMonitor.StatusChange += (o, a) => { Debug.LogMessage(LogEventLevel.Verbose, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
|
||||||
CommunicationMonitor.Start();
|
CommunicationMonitor.Start();
|
||||||
|
|
||||||
|
|
||||||
CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
|
CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// LinkToApi method
|
/// LinkToApi method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||||
{
|
{
|
||||||
LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge);
|
LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
|
void Socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString());
|
Debug.LogMessage(LogEventLevel.Verbose, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString());
|
||||||
|
|
||||||
if (e.Client.IsConnected)
|
if (e.Client.IsConnected)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SendBytes(byte[] b)
|
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
|
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));
|
Debug.LogMessage(LogEventLevel.Verbose, this, "Sending:{0}", ComTextHelper.GetEscapedText(b));
|
||||||
|
|
||||||
Communication.SendBytes(b);
|
Communication.SendBytes(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
|
void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
|
||||||
{
|
{
|
||||||
var newBytes = new byte[IncomingBuffer.Length + e.Bytes.Length];
|
var newBytes = new byte[IncomingBuffer.Length + e.Bytes.Length];
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -355,10 +382,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends a pan/tilt command. If the command is not for fastSpeed then it starts a timer to initiate fast speed.
|
/// Sends a pan/tilt command. If the command is not for fastSpeed then it starts a timer to initiate fast speed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cmd"></param>
|
/// <param name="cmd">The VISCA command to send</param>
|
||||||
/// <param name="fastSpeed"></param>
|
/// <param name="fastSpeedEnabled">Whether fast speed is enabled for this command</param>
|
||||||
private void SendPanTiltCommand (byte[] cmd, bool fastSpeedEnabled)
|
private void SendPanTiltCommand(byte[] cmd, bool fastSpeedEnabled)
|
||||||
{
|
{
|
||||||
SendBytes(GetPanTiltCommand(cmd, fastSpeedEnabled));
|
SendBytes(GetPanTiltCommand(cmd, fastSpeedEnabled));
|
||||||
|
|
||||||
if (!fastSpeedEnabled)
|
if (!fastSpeedEnabled)
|
||||||
@@ -372,7 +399,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
SpeedTimer = new CTimer((o) => SendPanTiltCommand(GetPanTiltCommand(cmd, true), true), FastSpeedHoldTimeMs);
|
SpeedTimer = new CTimer((o) => SendPanTiltCommand(GetPanTiltCommand(cmd, true), true), FastSpeedHoldTimeMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopSpeedTimer()
|
private void StopSpeedTimer()
|
||||||
{
|
{
|
||||||
@@ -424,14 +451,14 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
InquiryResponseQueue.Enqueue(HandlePowerResponse);
|
InquiryResponseQueue.Enqueue(HandlePowerResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PowerOn method
|
/// PowerOn method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void PowerOn()
|
public void PowerOn()
|
||||||
{
|
{
|
||||||
SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x02, 0xFF });
|
SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x02, 0xFF });
|
||||||
SendPowerQuery();
|
SendPowerQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandlePowerResponse(byte[] response)
|
void HandlePowerResponse(byte[] response)
|
||||||
{
|
{
|
||||||
@@ -450,12 +477,12 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PowerOff method
|
/// PowerOff method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void PowerOff()
|
public void PowerOff()
|
||||||
{
|
{
|
||||||
SendBytes(new byte[] {ID, 0x01, 0x04, 0x00, 0x03, 0xFF});
|
SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x03, 0xFF });
|
||||||
SendPowerQuery();
|
SendPowerQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,22 +497,22 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
PowerOn();
|
PowerOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PanLeft method
|
/// PanLeft method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void PanLeft()
|
public void PanLeft()
|
||||||
{
|
{
|
||||||
SendPanTiltCommand(new byte[] {0x01, 0x03}, false);
|
SendPanTiltCommand(new byte[] { 0x01, 0x03 }, false);
|
||||||
// IsMoving = true;
|
// IsMoving = true;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PanRight method
|
/// PanRight method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void PanRight()
|
public void PanRight()
|
||||||
{
|
{
|
||||||
SendPanTiltCommand(new byte[] { 0x02, 0x03 }, false);
|
SendPanTiltCommand(new byte[] { 0x02, 0x03 }, false);
|
||||||
// IsMoving = true;
|
// IsMoving = true;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PanStop method
|
/// PanStop method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -493,22 +520,22 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TiltDown method
|
/// TiltDown method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void TiltDown()
|
public void TiltDown()
|
||||||
{
|
{
|
||||||
SendPanTiltCommand(new byte[] { 0x03, 0x02 }, false);
|
SendPanTiltCommand(new byte[] { 0x03, 0x02 }, false);
|
||||||
// IsMoving = true;
|
// IsMoving = true;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TiltUp method
|
/// TiltUp method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void TiltUp()
|
public void TiltUp()
|
||||||
{
|
{
|
||||||
SendPanTiltCommand(new byte[] { 0x03, 0x01 }, false);
|
SendPanTiltCommand(new byte[] { 0x03, 0x01 }, false);
|
||||||
// IsMoving = true;
|
// IsMoving = true;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TiltStop method
|
/// TiltStop method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -517,28 +544,28 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendZoomCommand (byte cmd)
|
private void SendZoomCommand(byte cmd)
|
||||||
{
|
{
|
||||||
SendBytes(new byte[] {ID, 0x01, 0x04, 0x07, cmd, 0xFF} );
|
SendBytes(new byte[] { ID, 0x01, 0x04, 0x07, cmd, 0xFF });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ZoomIn method
|
/// ZoomIn method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ZoomIn()
|
public void ZoomIn()
|
||||||
{
|
{
|
||||||
SendZoomCommand(ZoomInCmd);
|
SendZoomCommand(ZoomInCmd);
|
||||||
IsZooming = true;
|
IsZooming = true;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ZoomOut method
|
/// ZoomOut method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ZoomOut()
|
public void ZoomOut()
|
||||||
{
|
{
|
||||||
SendZoomCommand(ZoomOutCmd);
|
SendZoomCommand(ZoomOutCmd);
|
||||||
IsZooming = true;
|
IsZooming = true;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ZoomStop method
|
/// ZoomStop method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -547,23 +574,23 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stop method
|
/// Stop method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
if (IsZooming)
|
if (IsZooming)
|
||||||
{
|
{
|
||||||
SendZoomCommand(ZoomStopCmd);
|
SendZoomCommand(ZoomStopCmd);
|
||||||
IsZooming = false;
|
IsZooming = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StopSpeedTimer();
|
StopSpeedTimer();
|
||||||
SendPanTiltCommand(new byte[] { 0x03, 0x03 }, false);
|
SendPanTiltCommand(new byte[] { 0x03, 0x03 }, false);
|
||||||
// IsMoving = false;
|
// IsMoving = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PositionHome method
|
/// PositionHome method
|
||||||
/// </summary>
|
/// </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, 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 });
|
SendBytes(new byte[] { ID, 0x01, 0x04, 0x47, 0x00, 0x00, 0x00, 0x00, 0xFF });
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// RecallPreset method
|
/// RecallPreset method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void RecallPreset(int presetNumber)
|
public void RecallPreset(int presetNumber)
|
||||||
{
|
{
|
||||||
SendBytes(new byte[] {ID, 0x01, 0x04, 0x3F, 0x02, (byte)presetNumber, 0xFF} );
|
SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x02, (byte)presetNumber, 0xFF });
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SavePreset method
|
/// SavePreset method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SavePreset(int presetNumber)
|
public void SavePreset(int presetNumber)
|
||||||
{
|
{
|
||||||
SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF });
|
SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF });
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IHasCameraPresets Members
|
#region IHasCameraPresets Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when the presets list has changed
|
||||||
|
/// </summary>
|
||||||
public event EventHandler<EventArgs> PresetsListHasChanged;
|
public event EventHandler<EventArgs> PresetsListHasChanged;
|
||||||
|
|
||||||
protected void OnPresetsListHasChanged()
|
/// <summary>
|
||||||
{
|
/// Raises the PresetsListHasChanged event
|
||||||
var handler = PresetsListHasChanged;
|
/// </summary>
|
||||||
if (handler == null)
|
protected void OnPresetsListHasChanged()
|
||||||
return;
|
{
|
||||||
|
var handler = PresetsListHasChanged;
|
||||||
|
if (handler == null)
|
||||||
|
return;
|
||||||
|
|
||||||
handler.Invoke(this, EventArgs.Empty);
|
handler.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Presets
|
/// Gets or sets the Presets
|
||||||
@@ -741,6 +774,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CameraViscaFactory : EssentialsDeviceFactory<CameraVisca>
|
public class CameraViscaFactory : EssentialsDeviceFactory<CameraVisca>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the CameraViscaFactory class
|
||||||
|
/// </summary>
|
||||||
public CameraViscaFactory()
|
public CameraViscaFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string>() { "cameravisca" };
|
TypeNames = new List<string>() { "cameravisca" };
|
||||||
@@ -768,11 +804,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Control ID of the camera (1-7)
|
/// Control ID of the camera (1-7)
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("id")]
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the Id
|
/// Gets or sets the Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("id")]
|
||||||
public uint Id { get; set; }
|
public uint Id { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||||
{
|
{
|
||||||
@@ -11,12 +8,27 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraPresets
|
public interface IHasCameraPresets
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when the presets list has changed
|
||||||
|
/// </summary>
|
||||||
event EventHandler<EventArgs> PresetsListHasChanged;
|
event EventHandler<EventArgs> PresetsListHasChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the list of camera presets
|
||||||
|
/// </summary>
|
||||||
List<CameraPreset> Presets { get; }
|
List<CameraPreset> Presets { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Selects the specified preset
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="preset">The preset number to select</param>
|
||||||
void PresetSelect(int preset);
|
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);
|
void PresetStore(int preset, string description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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.Core;
|
||||||
using PepperDash.Essentials.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
|
namespace PepperDash.Essentials.Devices.Common.Codec.Cisco
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.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
|
namespace PepperDash.Essentials.Devices.Common.Codec.Cisco
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
@@ -17,55 +13,55 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CodecActiveCallItem
|
public class CodecActiveCallItem
|
||||||
{
|
{
|
||||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Name
|
/// Gets or sets the Name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
[JsonProperty("number", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Number
|
/// Gets or sets the Number
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("number", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public string Number { get; set; }
|
public string Number { get; set; }
|
||||||
|
|
||||||
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Type
|
/// Gets or sets the Type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public eCodecCallType Type { get; set; }
|
public eCodecCallType Type { get; set; }
|
||||||
|
|
||||||
[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Status
|
/// Gets or sets the Status
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public eCodecCallStatus Status { get; set; }
|
public eCodecCallStatus Status { get; set; }
|
||||||
|
|
||||||
[JsonProperty("direction", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Direction
|
/// Gets or sets the Direction
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("direction", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public eCodecCallDirection Direction { get; set; }
|
public eCodecCallDirection Direction { get; set; }
|
||||||
|
|
||||||
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Id
|
/// Gets or sets the Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
[JsonProperty("isOnHold", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the IsOnHold
|
/// Gets or sets the IsOnHold
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("isOnHold", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public bool IsOnHold { get; set; }
|
public bool IsOnHold { get; set; }
|
||||||
|
|
||||||
[JsonProperty("duration", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Duration
|
/// Gets or sets the Duration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("duration", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public TimeSpan Duration { get; set; }
|
public TimeSpan Duration { get; set; }
|
||||||
|
|
||||||
//public object CallMetaData { get; set; }
|
//public object CallMetaData { get; set; }
|
||||||
@@ -81,7 +77,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
{
|
{
|
||||||
return !(Status == eCodecCallStatus.Disconnected
|
return !(Status == eCodecCallStatus.Disconnected
|
||||||
|| Status == eCodecCallStatus.Disconnecting
|
|| Status == eCodecCallStatus.Disconnecting
|
||||||
|| Status == eCodecCallStatus.Idle
|
|| Status == eCodecCallStatus.Idle
|
||||||
|| Status == eCodecCallStatus.Unknown);
|
|| Status == eCodecCallStatus.Unknown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,6 +93,10 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public CodecActiveCallItem CallItem { get; private set; }
|
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)
|
public CodecCallStatusItemChangeEventArgs(CodecActiveCallItem item)
|
||||||
{
|
{
|
||||||
CallItem = 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;
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes a cisco codec device that can allow configuration of cameras
|
/// Describes a cisco codec device that can allow configuration of cameras
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ICiscoCodecCameraConfig
|
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);
|
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);
|
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);
|
void SetInputSourceType(uint videoConnectorId, eCiscoCodecInputSourceType sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enumeration of Cisco codec input source types
|
||||||
|
/// </summary>
|
||||||
public enum eCiscoCodecInputSourceType
|
public enum eCiscoCodecInputSourceType
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// PC source type
|
||||||
|
/// </summary>
|
||||||
PC,
|
PC,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Camera source type
|
||||||
|
/// </summary>
|
||||||
camera,
|
camera,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Document camera source type
|
||||||
|
/// </summary>
|
||||||
document_camera,
|
document_camera,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Media player source type
|
||||||
|
/// </summary>
|
||||||
mediaplayer,
|
mediaplayer,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Other source type
|
||||||
|
/// </summary>
|
||||||
other,
|
other,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whiteboard source type
|
||||||
|
/// </summary>
|
||||||
whiteboard
|
whiteboard
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IHasCallHold
|
/// 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 PepperDash.Essentials.Core;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
using PepperDash.Essentials.Core;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
{
|
{
|
||||||
@@ -34,6 +28,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
void ToggleDoNotDisturbMode();
|
void ToggleDoNotDisturbMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the contract for devices that support Do Not Disturb mode with timeout functionality
|
||||||
|
/// </summary>
|
||||||
public interface IHasDoNotDisturbModeWithTimeout : IHasDoNotDisturbMode
|
public interface IHasDoNotDisturbModeWithTimeout : IHasDoNotDisturbMode
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,25 +1,54 @@
|
|||||||
using System;
|
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;
|
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IHasExternalSourceSwitching
|
/// Defines the contract for IHasExternalSourceSwitching
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasExternalSourceSwitching
|
public interface IHasExternalSourceSwitching
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the external source list is enabled
|
||||||
|
/// </summary>
|
||||||
bool ExternalSourceListEnabled { get; }
|
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);
|
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);
|
void SetExternalSourceState(string key, eExternalSourceMode mode);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears all external sources from the list
|
||||||
|
/// </summary>
|
||||||
void ClearExternalSources();
|
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;
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -12,7 +6,20 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum eCodecCallDirection
|
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>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,27 +1,68 @@
|
|||||||
using System;
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enumeration of eCodecCallStatus values
|
/// Enumeration of eCodecCallStatus values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum eCodecCallStatus
|
public enum eCodecCallStatus
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unknown call status
|
||||||
|
/// </summary>
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call is connected
|
||||||
|
/// </summary>
|
||||||
Connected,
|
Connected,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call is connecting
|
||||||
|
/// </summary>
|
||||||
Connecting,
|
Connecting,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call is dialing
|
||||||
|
/// </summary>
|
||||||
Dialing,
|
Dialing,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call is disconnected
|
||||||
|
/// </summary>
|
||||||
Disconnected,
|
Disconnected,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call is disconnecting
|
||||||
|
/// </summary>
|
||||||
Disconnecting,
|
Disconnecting,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Early media is being sent/received
|
||||||
|
/// </summary>
|
||||||
EarlyMedia,
|
EarlyMedia,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call is idle
|
||||||
|
/// </summary>
|
||||||
Idle,
|
Idle,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call is on hold
|
||||||
|
/// </summary>
|
||||||
OnHold,
|
OnHold,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call is ringing
|
||||||
|
/// </summary>
|
||||||
Ringing,
|
Ringing,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call is preserved
|
||||||
|
/// </summary>
|
||||||
Preserved,
|
Preserved,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call is remote preserved
|
||||||
|
/// </summary>
|
||||||
RemotePreserved,
|
RemotePreserved,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -12,10 +6,29 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum eCodecCallType
|
public enum eCodecCallType
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unknown call type
|
||||||
|
/// </summary>
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Audio-only call type
|
||||||
|
/// </summary>
|
||||||
Audio,
|
Audio,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Video call type
|
||||||
|
/// </summary>
|
||||||
Video,
|
Video,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Audio call that can be escalated to video
|
||||||
|
/// </summary>
|
||||||
AudioCanEscalate,
|
AudioCanEscalate,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Forward all call type
|
||||||
|
/// </summary>
|
||||||
ForwardAllCall
|
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;
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enumeration of eMeetingPrivacy values
|
/// Enumeration of eMeetingPrivacy values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum eMeetingPrivacy
|
public enum eMeetingPrivacy
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unknown meeting privacy level
|
||||||
|
/// </summary>
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Public meeting
|
||||||
|
/// </summary>
|
||||||
Public,
|
Public,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Private meeting
|
||||||
|
/// </summary>
|
||||||
Private
|
Private
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
using PepperDash.Essentials.Core;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
using PepperDash.Essentials.Core;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
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
|
||||||
{
|
{
|
||||||
@@ -11,6 +7,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCallFavorites
|
public interface IHasCallFavorites
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the call favorites for this device
|
||||||
|
/// </summary>
|
||||||
CodecCallFavorites CallFavorites { get; }
|
CodecCallFavorites CallFavorites { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,6 +23,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public List<CodecActiveCallItem> Favorites { get; set; }
|
public List<CodecActiveCallItem> Favorites { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the CodecCallFavorites class
|
||||||
|
/// </summary>
|
||||||
public CodecCallFavorites()
|
public CodecCallFavorites()
|
||||||
{
|
{
|
||||||
Favorites = new List<CodecActiveCallItem>();
|
Favorites = new List<CodecActiveCallItem>();
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
{
|
{
|
||||||
@@ -15,8 +14,15 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCallHistory
|
public interface IHasCallHistory
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the call history for this device
|
||||||
|
/// </summary>
|
||||||
CodecCallHistory CallHistory { get; }
|
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);
|
void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,9 +31,24 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum eCodecOccurrenceType
|
public enum eCodecOccurrenceType
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unknown occurrence type
|
||||||
|
/// </summary>
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call was placed (outgoing)
|
||||||
|
/// </summary>
|
||||||
Placed = 1,
|
Placed = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call was received (incoming)
|
||||||
|
/// </summary>
|
||||||
Received = 2,
|
Received = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call received no answer
|
||||||
|
/// </summary>
|
||||||
NoAnswer = 3,
|
NoAnswer = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +57,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CodecCallHistory
|
public class CodecCallHistory
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when the recent calls list has changed
|
||||||
|
/// </summary>
|
||||||
public event EventHandler<EventArgs> RecentCallsListHasChanged;
|
public event EventHandler<EventArgs> RecentCallsListHasChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -48,6 +72,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
CallHistoryEntry ListEmptyEntry;
|
CallHistoryEntry ListEmptyEntry;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the CodecCallHistory class
|
||||||
|
/// </summary>
|
||||||
public CodecCallHistory()
|
public CodecCallHistory()
|
||||||
{
|
{
|
||||||
ListEmptyEntry = new CallHistoryEntry() { Name = "No Recent Calls" };
|
ListEmptyEntry = new CallHistoryEntry() { Name = "No Recent Calls" };
|
||||||
@@ -80,15 +107,22 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CallHistoryEntry : CodecActiveCallItem
|
public class CallHistoryEntry : CodecActiveCallItem
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(IsoDateTimeConverter))]
|
|
||||||
[JsonProperty("startTime")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the StartTime
|
/// Gets or sets the StartTime
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonConverter(typeof(IsoDateTimeConverter))]
|
||||||
|
[JsonProperty("startTime")]
|
||||||
public DateTime StartTime { get; set; }
|
public DateTime StartTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the occurrence type for this call history entry
|
||||||
|
/// </summary>
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
[JsonProperty("occurrenceType")]
|
[JsonProperty("occurrenceType")]
|
||||||
public eCodecOccurrenceType OccurrenceType { get; set; }
|
public eCodecOccurrenceType OccurrenceType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the occurrence history identifier
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("occurrenceHistoryId")]
|
[JsonProperty("occurrenceHistoryId")]
|
||||||
public string OccurrenceHistoryId { get; set; }
|
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
|
// 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);
|
genericEntries.Add(ListEmptyEntry);
|
||||||
|
|
||||||
RecentCalls = genericEntries;
|
RecentCalls = genericEntries;
|
||||||
|
|||||||
@@ -1,11 +1,4 @@
|
|||||||
using System;
|
using PepperDash.Essentials.Core;
|
||||||
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.Codec
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
@@ -15,12 +8,29 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasContentSharing
|
public interface IHasContentSharing
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets feedback indicating whether content sharing is currently active
|
||||||
|
/// </summary>
|
||||||
BoolFeedback SharingContentIsOnFeedback { get; }
|
BoolFeedback SharingContentIsOnFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets feedback about the current sharing source
|
||||||
|
/// </summary>
|
||||||
StringFeedback SharingSourceFeedback { get; }
|
StringFeedback SharingSourceFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether content should be automatically shared while in a call
|
||||||
|
/// </summary>
|
||||||
bool AutoShareContentWhileInCall { get; }
|
bool AutoShareContentWhileInCall { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts content sharing
|
||||||
|
/// </summary>
|
||||||
void StartSharing();
|
void StartSharing();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops content sharing
|
||||||
|
/// </summary>
|
||||||
void StopSharing();
|
void StopSharing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
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
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
{
|
{
|
||||||
@@ -15,15 +9,49 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
{
|
{
|
||||||
// Add requirements for Dialer functionality
|
// Add requirements for Dialer functionality
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when call status changes
|
||||||
|
/// </summary>
|
||||||
event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
|
event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dials the specified number
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="number">The number to dial</param>
|
||||||
void Dial(string number);
|
void Dial(string number);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ends the specified active call
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="activeCall">The active call to end</param>
|
||||||
void EndCall(CodecActiveCallItem activeCall);
|
void EndCall(CodecActiveCallItem activeCall);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ends all active calls
|
||||||
|
/// </summary>
|
||||||
void EndAllCalls();
|
void EndAllCalls();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Accepts the specified incoming call
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The call item to accept</param>
|
||||||
void AcceptCall(CodecActiveCallItem item);
|
void AcceptCall(CodecActiveCallItem item);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rejects the specified incoming call
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The call item to reject</param>
|
||||||
void RejectCall(CodecActiveCallItem item);
|
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);
|
void SendDtmf(string digit);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the device is currently in a call
|
||||||
|
/// </summary>
|
||||||
bool IsInCall { get; }
|
bool IsInCall { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,319 +1,59 @@
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Converters;
|
|
||||||
|
|
||||||
|
|
||||||
using PepperDash.Core;
|
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the API for codecs with a directory
|
/// Defines the API for codecs with a directory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasDirectory
|
public interface IHasDirectory
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event that fires when a directory result is returned from the codec
|
||||||
|
/// </summary>
|
||||||
event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
|
event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the DirectoryRoot
|
||||||
|
/// </summary>
|
||||||
CodecDirectory DirectoryRoot { get; }
|
CodecDirectory DirectoryRoot { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the CurrentDirectoryResult
|
||||||
|
/// </summary>
|
||||||
CodecDirectory CurrentDirectoryResult { get; }
|
CodecDirectory CurrentDirectoryResult { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the PhonebookSyncState
|
||||||
|
/// </summary>
|
||||||
CodecPhonebookSyncState PhonebookSyncState { get; }
|
CodecPhonebookSyncState PhonebookSyncState { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method to initiate a search of the directory on the server
|
||||||
|
/// </summary>
|
||||||
void SearchDirectory(string searchString);
|
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);
|
void GetDirectoryFolderContents(string folderId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method to set the current directory to the root folder
|
||||||
|
/// </summary>
|
||||||
void SetCurrentDirectoryToRoot();
|
void SetCurrentDirectoryToRoot();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method to get the contents of the parent folder in the directory on the server
|
||||||
|
/// </summary>
|
||||||
void GetDirectoryParentFolderContents();
|
void GetDirectoryParentFolderContents();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the CurrentDirectoryResultIsNotDirectoryRoot
|
||||||
|
/// </summary>
|
||||||
BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; }
|
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 @@
|
|||||||
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
[Flags]
|
|
||||||
/// <summary>
|
|
||||||
/// Enumeration of eMeetingEventChangeType values
|
|
||||||
/// </summary>
|
|
||||||
public enum eMeetingEventChangeType
|
|
||||||
{
|
|
||||||
Unknown = 0,
|
|
||||||
MeetingStartWarning = 1,
|
|
||||||
MeetingStart = 2,
|
|
||||||
MeetingEndWarning = 4,
|
|
||||||
MeetingEnd = 8
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IHasScheduleAwareness
|
/// Defines the contract for IHasScheduleAwareness
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasScheduleAwareness
|
public interface IHasScheduleAwareness
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the CodecScheduleAwareness instance
|
||||||
|
/// </summary>
|
||||||
CodecScheduleAwareness CodecSchedule { get; }
|
CodecScheduleAwareness CodecSchedule { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method to initiate getting the schedule from the server
|
||||||
|
/// </summary>
|
||||||
void GetSchedule();
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
using PepperDash.Essentials.Devices.Common.Codec;
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.DSP
|
namespace PepperDash.Essentials.Devices.Common.DSP
|
||||||
{
|
{
|
||||||
public abstract class DspBase : EssentialsDevice, ILevelControls
|
/// <summary>
|
||||||
{
|
/// Base class for DSP devices
|
||||||
public Dictionary<string,IBasicVolumeWithFeedback> LevelControlPoints { get; private set; }
|
/// </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; }
|
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 Dictionary<string, DspControlPoint> SwitcherControlPoints { get; private set; }
|
||||||
|
|
||||||
public DspBase(string key, string name) :
|
/// <summary>
|
||||||
base(key, name)
|
/// 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>();
|
LevelControlPoints = new Dictionary<string, IBasicVolumeWithFeedback>();
|
||||||
DialerControlPoints = new Dictionary<string, DspControlPoint>();
|
DialerControlPoints = new Dictionary<string, DspControlPoint>();
|
||||||
SwitcherControlPoints = new Dictionary<string, DspControlPoint>();
|
SwitcherControlPoints = new Dictionary<string, DspControlPoint>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// in audio call feedback
|
// in audio call feedback
|
||||||
|
|
||||||
// VOIP
|
// VOIP
|
||||||
// Phone dialer
|
// Phone dialer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fusion
|
// Fusion
|
||||||
// Privacy state
|
// Privacy state
|
||||||
// Online state
|
// Online state
|
||||||
// level/mutes ?
|
// level/mutes ?
|
||||||
|
|
||||||
// AC Log call stats
|
// AC Log call stats
|
||||||
|
|
||||||
// Typical presets:
|
// Typical presets:
|
||||||
// call default preset to restore levels and mutes
|
// call default preset to restore levels and mutes
|
||||||
|
|
||||||
public abstract class DspControlPoint :IKeyed
|
/// <summary>
|
||||||
{
|
/// Base class for DSP control points
|
||||||
|
/// </summary>
|
||||||
|
public abstract class DspControlPoint : IKeyed
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Key
|
/// Gets or sets the Key
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Key { get; }
|
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;
|
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>
|
/// <summary>
|
||||||
/// Gets or sets the MuteFeedback
|
/// Gets or sets the MuteFeedback
|
||||||
@@ -66,30 +89,63 @@ namespace PepperDash.Essentials.Devices.Common.DSP
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IntFeedback VolumeLevelFeedback { get; }
|
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)
|
protected DspLevelControlPoint(string key, Func<bool> muteFeedbackFunc, Func<int> volumeLevelFeedbackFunc) : base(key)
|
||||||
{
|
{
|
||||||
MuteFeedback = new BoolFeedback(muteFeedbackFunc);
|
MuteFeedback = new BoolFeedback("mute", muteFeedbackFunc);
|
||||||
VolumeLevelFeedback = new IntFeedback(volumeLevelFeedbackFunc);
|
VolumeLevelFeedback = new IntFeedback("volume", volumeLevelFeedbackFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turns mute off
|
||||||
|
/// </summary>
|
||||||
public abstract void MuteOff();
|
public abstract void MuteOff();
|
||||||
|
/// <summary>
|
||||||
|
/// Turns mute on
|
||||||
|
/// </summary>
|
||||||
public abstract void MuteOn();
|
public abstract void MuteOn();
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles mute state
|
||||||
|
/// </summary>
|
||||||
public abstract void MuteToggle();
|
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);
|
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);
|
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 void VolumeUp(bool pressRelease);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
public abstract class DspDialerBase:DspControlPoint
|
/// 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) { }
|
protected DspDialerBase(string key) : base(key) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Main program
|
// Main program
|
||||||
// VTC
|
// VTC
|
||||||
// ATC
|
// ATC
|
||||||
// Mics, unusual
|
// Mics, unusual
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,9 @@ namespace PepperDash.Essentials.Devices.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DeviceFactory
|
public class DeviceFactory
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the DeviceFactory class
|
||||||
|
/// </summary>
|
||||||
public DeviceFactory()
|
public DeviceFactory()
|
||||||
{
|
{
|
||||||
var assy = Assembly.GetExecutingAssembly();
|
var assy = Assembly.GetExecutingAssembly();
|
||||||
|
|||||||
@@ -11,37 +11,53 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Displays
|
namespace PepperDash.Essentials.Devices.Common.Displays
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a BasicIrDisplay
|
/// Represents a BasicIrDisplay
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced
|
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the IrPort
|
/// Gets or sets the IrPort
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IrOutputPortController IrPort { get; private set; }
|
public IrOutputPortController IrPort { get; private set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the IrPulseTime
|
/// Gets or sets the IrPulseTime
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ushort IrPulseTime { get; set; }
|
public ushort IrPulseTime { get; set; }
|
||||||
|
|
||||||
protected Func<bool> PowerIsOnFeedbackFunc
|
/// <summary>
|
||||||
{
|
/// Gets the power is on feedback function
|
||||||
get { return () => _PowerIsOn; }
|
/// </summary>
|
||||||
}
|
protected Func<bool> PowerIsOnFeedbackFunc
|
||||||
|
{
|
||||||
|
get { return () => _PowerIsOn; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the is cooling down feedback function
|
||||||
|
/// </summary>
|
||||||
protected override Func<bool> IsCoolingDownFeedbackFunc
|
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||||
{
|
{
|
||||||
get { return () => _IsCoolingDown; }
|
get { return () => _IsCoolingDown; }
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the is warming up feedback function
|
||||||
|
/// </summary>
|
||||||
protected override Func<bool> IsWarmingUpFeedbackFunc
|
protected override Func<bool> IsWarmingUpFeedbackFunc
|
||||||
{
|
{
|
||||||
get { return () => _IsWarmingUp; }
|
get { return () => _IsWarmingUp; }
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _PowerIsOn;
|
bool _PowerIsOn;
|
||||||
bool _IsWarmingUp;
|
bool _IsWarmingUp;
|
||||||
bool _IsCoolingDown;
|
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)
|
public BasicIrDisplay(string key, string name, IROutputPort port, string irDriverFilepath)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
@@ -70,57 +86,57 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hdmi1 method
|
/// Hdmi1 method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Hdmi1()
|
public void Hdmi1()
|
||||||
{
|
{
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_1, IrPulseTime);
|
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_1, IrPulseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hdmi2 method
|
/// Hdmi2 method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Hdmi2()
|
public void Hdmi2()
|
||||||
{
|
{
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_2, IrPulseTime);
|
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_2, IrPulseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hdmi3 method
|
/// Hdmi3 method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Hdmi3()
|
public void Hdmi3()
|
||||||
{
|
{
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_3, IrPulseTime);
|
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_3, IrPulseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hdmi4 method
|
/// Hdmi4 method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Hdmi4()
|
public void Hdmi4()
|
||||||
{
|
{
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_4, IrPulseTime);
|
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_4, IrPulseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Component1 method
|
/// Component1 method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Component1()
|
public void Component1()
|
||||||
{
|
{
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_COMPONENT_1, IrPulseTime);
|
IrPort.Pulse(IROutputStandardCommands.IROut_COMPONENT_1, IrPulseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Video1 method
|
/// Video1 method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Video1()
|
public void Video1()
|
||||||
{
|
{
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_VIDEO_1, IrPulseTime);
|
IrPort.Pulse(IROutputStandardCommands.IROut_VIDEO_1, IrPulseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Antenna method
|
/// Antenna method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Antenna()
|
public void Antenna()
|
||||||
{
|
{
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_ANTENNA, IrPulseTime);
|
IrPort.Pulse(IROutputStandardCommands.IROut_ANTENNA, IrPulseTime);
|
||||||
@@ -128,31 +144,31 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
|
|
||||||
#region IPower Members
|
#region IPower Members
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PowerOn method
|
/// PowerOn method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void PowerOn()
|
public override void PowerOn()
|
||||||
{
|
{
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
|
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
|
||||||
_PowerIsOn = true;
|
_PowerIsOn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PowerOff method
|
/// PowerOff method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override void PowerOff()
|
public override void PowerOff()
|
||||||
{
|
{
|
||||||
_PowerIsOn = false;
|
_PowerIsOn = false;
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
|
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PowerToggle method
|
/// PowerToggle method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override void PowerToggle()
|
public override void PowerToggle()
|
||||||
{
|
{
|
||||||
_PowerIsOn = false;
|
_PowerIsOn = false;
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
|
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,25 +176,25 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
|
|
||||||
#region IBasicVolumeControls Members
|
#region IBasicVolumeControls Members
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// VolumeUp method
|
/// VolumeUp method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void VolumeUp(bool pressRelease)
|
public void VolumeUp(bool pressRelease)
|
||||||
{
|
{
|
||||||
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_PLUS, pressRelease);
|
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_PLUS, pressRelease);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// VolumeDown method
|
/// VolumeDown method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void VolumeDown(bool pressRelease)
|
public void VolumeDown(bool pressRelease)
|
||||||
{
|
{
|
||||||
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_MINUS, pressRelease);
|
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_MINUS, pressRelease);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MuteToggle method
|
/// MuteToggle method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void MuteToggle()
|
public void MuteToggle()
|
||||||
{
|
{
|
||||||
IrPort.Pulse(IROutputStandardCommands.IROut_MUTE, 200);
|
IrPort.Pulse(IROutputStandardCommands.IROut_MUTE, 200);
|
||||||
@@ -190,7 +206,8 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
{
|
{
|
||||||
_IsWarmingUp = true;
|
_IsWarmingUp = true;
|
||||||
IsWarmingUpFeedback.FireUpdate();
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
new CTimer(o => {
|
new CTimer(o =>
|
||||||
|
{
|
||||||
_IsWarmingUp = false;
|
_IsWarmingUp = false;
|
||||||
IsWarmingUpFeedback.FireUpdate();
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
}, 10000);
|
}, 10000);
|
||||||
@@ -213,13 +230,13 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
/// Typically called by the discovery routing algorithm.
|
/// Typically called by the discovery routing algorithm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="inputSelector">A delegate containing the input selector method to call</param>
|
/// <param name="inputSelector">A delegate containing the input selector method to call</param>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ExecuteSwitch method
|
/// ExecuteSwitch method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void ExecuteSwitch(object inputSelector)
|
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 = () =>
|
Action finishSwitch = () =>
|
||||||
{
|
{
|
||||||
@@ -246,42 +263,45 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// LinkToApi method
|
/// LinkToApi method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||||
{
|
{
|
||||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a BasicIrDisplayFactory
|
/// Represents a BasicIrDisplayFactory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BasicIrDisplayFactory : EssentialsDeviceFactory<BasicIrDisplay>
|
public class BasicIrDisplayFactory : EssentialsDeviceFactory<BasicIrDisplay>
|
||||||
{
|
{
|
||||||
public BasicIrDisplayFactory()
|
/// <summary>
|
||||||
{
|
/// Initializes a new instance of the BasicIrDisplayFactory class
|
||||||
TypeNames = new List<string>() { "basicirdisplay" };
|
/// </summary>
|
||||||
}
|
public BasicIrDisplayFactory()
|
||||||
|
{
|
||||||
|
TypeNames = new List<string>() { "basicirdisplay" };
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// BuildDevice method
|
/// BuildDevice method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BasicIrDisplay Device");
|
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BasicIrDisplay Device");
|
||||||
var ir = IRPortHelper.GetIrPort(dc.Properties);
|
var ir = IRPortHelper.GetIrPort(dc.Properties);
|
||||||
if (ir != null)
|
if (ir != null)
|
||||||
{
|
{
|
||||||
var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName);
|
var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName);
|
||||||
display.IrPulseTime = 200; // Set default pulse time for IR commands.
|
display.IrPulseTime = 200; // Set default pulse time for IR commands.
|
||||||
return display;
|
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
|
/// Abstract base class for display devices that provides common display functionality
|
||||||
/// including power control, input switching, and routing capabilities.
|
/// including power control, input switching, and routing capabilities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources
|
public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources, IHasFeedback
|
||||||
{
|
{
|
||||||
private RoutingInputPort _currentInputPort;
|
private RoutingInputPort _currentInputPort;
|
||||||
|
|
||||||
@@ -73,13 +73,11 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
|
|
||||||
var handler = CurrentSourceChange;
|
var handler = CurrentSourceChange;
|
||||||
|
|
||||||
if (handler != null)
|
handler?.Invoke(_CurrentSourceInfo, ChangeType.WillChange);
|
||||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
|
||||||
|
|
||||||
_CurrentSourceInfo = value;
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
if (handler != null)
|
handler?.Invoke(_CurrentSourceInfo, ChangeType.DidChange);
|
||||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SourceListItem _CurrentSourceInfo;
|
SourceListItem _CurrentSourceInfo;
|
||||||
@@ -160,6 +158,9 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
||||||
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
||||||
|
|
||||||
|
Feedbacks.Add(IsCoolingDownFeedback);
|
||||||
|
Feedbacks.Add(IsWarmingUpFeedback);
|
||||||
|
|
||||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||||
|
|
||||||
CurrentSources = new Dictionary<eRoutingSignalType, SourceListItem>
|
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.
|
/// Gets the collection of feedback objects for this display device.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual FeedbackCollection<Feedback> Feedbacks
|
public virtual FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return new FeedbackCollection<Feedback>
|
|
||||||
{
|
|
||||||
IsCoolingDownFeedback,
|
|
||||||
IsWarmingUpFeedback
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes a switch to the specified input on the display device. Must be implemented by derived classes.
|
/// 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>
|
/// <param name="joinMap">The join map configuration for the device.</param>
|
||||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, DisplayControllerJoinMap joinMap)
|
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, DisplayControllerJoinMap joinMap)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
this.LogDebug("Linking to Trilist {ipId}", trilist.ID.ToString("X"));
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Linking to Display: {0}", displayDevice.Name);
|
this.LogDebug("Linking to Display: {displayName}", displayDevice.Name);
|
||||||
|
|
||||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
|
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
|
||||||
|
|
||||||
var commMonitor = displayDevice as ICommunicationMonitor;
|
if (displayDevice is ICommunicationMonitor commMonitor)
|
||||||
if (commMonitor != null)
|
|
||||||
{
|
{
|
||||||
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: revisit this as there could be issues with this approach
|
||||||
var inputNumber = 0;
|
var inputNumber = 0;
|
||||||
var inputKeys = new List<string>();
|
var inputKeys = new List<string>();
|
||||||
|
|
||||||
var inputNumberFeedback = new IntFeedback(() => inputNumber);
|
var inputNumberFeedback = new IntFeedback("inputNumber", () => inputNumber);
|
||||||
|
|
||||||
|
// Add input number feedback to the device feedback collection to keep it around...
|
||||||
|
Feedbacks.Add(inputNumberFeedback);
|
||||||
|
|
||||||
// Two way feedbacks
|
// Two way feedbacks
|
||||||
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
|
if (displayDevice is TwoWayDisplayBase twoWayDisplay)
|
||||||
|
|
||||||
if (twoWayDisplay != null)
|
|
||||||
{
|
{
|
||||||
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
|
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]);
|
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
|
||||||
}
|
|
||||||
|
|
||||||
// Power Off
|
twoWayDisplay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
|
|
||||||
{
|
|
||||||
inputNumber = 102;
|
|
||||||
inputNumberFeedback.FireUpdate();
|
|
||||||
displayDevice.PowerOff();
|
|
||||||
});
|
|
||||||
|
|
||||||
var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase;
|
|
||||||
if (twoWayDisplayDevice != null)
|
|
||||||
{
|
|
||||||
twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
|
|
||||||
{
|
{
|
||||||
if (!a.BoolValue)
|
if (!a.BoolValue)
|
||||||
{
|
{
|
||||||
@@ -307,10 +287,18 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
|
twoWayDisplay.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
|
||||||
twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
|
twoWayDisplay.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Power Off
|
||||||
|
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
|
||||||
|
{
|
||||||
|
inputNumber = 102;
|
||||||
|
inputNumberFeedback.FireUpdate();
|
||||||
|
displayDevice.PowerOff();
|
||||||
|
});
|
||||||
|
|
||||||
// PowerOn
|
// PowerOn
|
||||||
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
|
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
|
||||||
{
|
{
|
||||||
@@ -320,44 +308,61 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
|
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);
|
this.LogWarning("Device has {inputCount} inputs. The Join Map allows up to {joinSpan} inputs. Discarding inputs {discardStart} - {discardEnd} from bridge.",
|
||||||
var tempKey = inputKeys.ElementAt(i);
|
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, localindex + 1, displayDevice.InputPorts.Count);
|
||||||
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
|
|
||||||
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
|
continue;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
else
|
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);
|
this.LogDebug("Setting Input Select Action on Analog Join {inputSelectJoin}", joinMap.InputSelect);
|
||||||
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
|
|
||||||
|
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (requestedInput) =>
|
||||||
{
|
{
|
||||||
if (a == 0)
|
if (requestedInput == 0)
|
||||||
{
|
{
|
||||||
displayDevice.PowerOff();
|
displayDevice.PowerOff();
|
||||||
inputNumber = 0;
|
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);
|
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(requestedInput - 1).Selector);
|
||||||
inputNumber = a;
|
|
||||||
|
inputNumber = requestedInput;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (a == 102)
|
|
||||||
|
if (requestedInput == 102)
|
||||||
{
|
{
|
||||||
displayDevice.PowerToggle();
|
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;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Displays
|
namespace PepperDash.Essentials.Devices.Displays
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IInputHdmi1
|
/// Defines the contract for IInputHdmi1
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IInputHdmi1 { void InputHdmi1(); }
|
[Obsolete()]
|
||||||
|
public interface IInputHdmi1
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Switches to HDMI 1 input
|
||||||
|
/// </summary>
|
||||||
|
void InputHdmi1();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IInputHdmi2
|
/// Defines the contract for IInputHdmi2
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IInputHdmi2 { void InputHdmi2(); }
|
[Obsolete()]
|
||||||
|
public interface IInputHdmi2
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Switches to HDMI 2 input
|
||||||
|
/// </summary>
|
||||||
|
void InputHdmi2();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IInputHdmi3
|
/// Defines the contract for IInputHdmi3
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IInputHdmi3 { void InputHdmi3(); }
|
[Obsolete()]
|
||||||
|
public interface IInputHdmi3
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Switches to HDMI 3 input
|
||||||
|
/// </summary>
|
||||||
|
void InputHdmi3();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IInputHdmi4
|
/// Defines the contract for IInputHdmi4
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IInputHdmi4 { void InputHdmi4(); }
|
[Obsolete()]
|
||||||
|
public interface IInputHdmi4
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Switches to HDMI 4 input
|
||||||
|
/// </summary>
|
||||||
|
void InputHdmi4();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IInputDisplayPort1
|
/// Defines the contract for IInputDisplayPort1
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IInputDisplayPort1 { void InputDisplayPort1(); }
|
[Obsolete()]
|
||||||
|
public interface IInputDisplayPort1
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Switches to DisplayPort 1 input
|
||||||
|
/// </summary>
|
||||||
|
void InputDisplayPort1();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IInputDisplayPort2
|
/// Defines the contract for IInputDisplayPort2
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IInputDisplayPort2 { void InputDisplayPort2(); }
|
[Obsolete()]
|
||||||
|
public interface IInputDisplayPort2
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Switches to DisplayPort 2 input
|
||||||
|
/// </summary>
|
||||||
|
void InputDisplayPort2();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IInputVga1
|
/// Defines the contract for IInputVga1
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IInputVga1 { void InputVga1(); }
|
[Obsolete()]
|
||||||
|
public interface IInputVga1
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Switches to VGA 1 input
|
||||||
|
/// </summary>
|
||||||
|
void InputVga1();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -16,16 +16,19 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
/// Represents a MockDisplay
|
/// Represents a MockDisplay
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs<string>, IRoutingSinkWithSwitchingWithInputPort, IHasPowerControlWithFeedback
|
public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs<string>, IRoutingSinkWithSwitchingWithInputPort, IHasPowerControlWithFeedback
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Inputs
|
/// Gets or sets the Inputs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ISelectableItems<string> Inputs { get; private set; }
|
public ISelectableItems<string> Inputs { get; private set; }
|
||||||
|
|
||||||
bool _PowerIsOn;
|
bool _PowerIsOn;
|
||||||
bool _IsWarmingUp;
|
bool _IsWarmingUp;
|
||||||
bool _IsCoolingDown;
|
bool _IsCoolingDown;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the power is on feedback function
|
||||||
|
/// </summary>
|
||||||
protected override Func<bool> PowerIsOnFeedbackFunc
|
protected override Func<bool> PowerIsOnFeedbackFunc
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -34,8 +37,12 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
{
|
{
|
||||||
return _PowerIsOn;
|
return _PowerIsOn;
|
||||||
};
|
};
|
||||||
} }
|
}
|
||||||
protected override Func<bool> IsCoolingDownFeedbackFunc
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the is cooling down feedback function
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -45,7 +52,10 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected override Func<bool> IsWarmingUpFeedbackFunc
|
/// <summary>
|
||||||
|
/// Gets the is warming up feedback function
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingUpFeedbackFunc
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -55,120 +65,128 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current input feedback function
|
||||||
|
/// </summary>
|
||||||
protected override Func<string> CurrentInputFeedbackFunc { get { return () => Inputs.CurrentItem; } }
|
protected override Func<string> CurrentInputFeedbackFunc { get { return () => Inputs.CurrentItem; } }
|
||||||
|
|
||||||
int VolumeHeldRepeatInterval = 200;
|
int VolumeHeldRepeatInterval = 200;
|
||||||
ushort VolumeInterval = 655;
|
ushort VolumeInterval = 655;
|
||||||
ushort _FakeVolumeLevel = 31768;
|
ushort _FakeVolumeLevel = 31768;
|
||||||
bool _IsMuted;
|
bool _IsMuted;
|
||||||
|
|
||||||
public MockDisplay(string key, string name)
|
/// <summary>
|
||||||
: base(key, name)
|
/// Initializes a new instance of the MockDisplay class
|
||||||
{
|
/// </summary>
|
||||||
|
/// <param name="key">The device key</param>
|
||||||
|
/// <param name="name">The device name</param>
|
||||||
|
public MockDisplay(string key, string name)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
Inputs = new MockDisplayInputs
|
Inputs = new MockDisplayInputs
|
||||||
{
|
{
|
||||||
Items = new Dictionary<string, ISelectableItem>
|
Items = new Dictionary<string, ISelectableItem>
|
||||||
{
|
{
|
||||||
{ "HDMI1", new MockDisplayInput ( "HDMI1", "HDMI 1",this ) },
|
{ "HDMI1", new MockDisplayInput ( "HDMI1", "HDMI 1",this ) },
|
||||||
{ "HDMI2", new MockDisplayInput ("HDMI2", "HDMI 2",this ) },
|
{ "HDMI2", new MockDisplayInput ("HDMI2", "HDMI 2",this ) },
|
||||||
{ "HDMI3", new MockDisplayInput ("HDMI3", "HDMI 3",this ) },
|
{ "HDMI3", new MockDisplayInput ("HDMI3", "HDMI 3",this ) },
|
||||||
{ "HDMI4", new MockDisplayInput ("HDMI4", "HDMI 4",this )},
|
{ "HDMI4", new MockDisplayInput ("HDMI4", "HDMI 4",this )},
|
||||||
{ "DP", new MockDisplayInput ("DP", "DisplayPort", this ) }
|
{ "DP", new MockDisplayInput ("DP", "DisplayPort", this ) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Inputs.CurrentItemChanged += (o, a) => CurrentInputFeedback.FireUpdate();
|
Inputs.CurrentItemChanged += (o, a) => CurrentInputFeedback.FireUpdate();
|
||||||
|
|
||||||
var hdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
|
var hdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
|
||||||
eRoutingPortConnectionType.Hdmi, "HDMI1", this);
|
eRoutingPortConnectionType.Hdmi, "HDMI1", this);
|
||||||
var hdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
|
var hdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
|
||||||
eRoutingPortConnectionType.Hdmi, "HDMI2", this);
|
eRoutingPortConnectionType.Hdmi, "HDMI2", this);
|
||||||
var hdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
|
var hdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
|
||||||
eRoutingPortConnectionType.Hdmi, "HDMI3", this);
|
eRoutingPortConnectionType.Hdmi, "HDMI3", this);
|
||||||
var hdmiIn4 = new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo,
|
var hdmiIn4 = new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo,
|
||||||
eRoutingPortConnectionType.Hdmi, "HDMI4", this);
|
eRoutingPortConnectionType.Hdmi, "HDMI4", this);
|
||||||
var dpIn = new RoutingInputPort(RoutingPortNames.DisplayPortIn, eRoutingSignalType.AudioVideo,
|
var dpIn = new RoutingInputPort(RoutingPortNames.DisplayPortIn, eRoutingSignalType.AudioVideo,
|
||||||
eRoutingPortConnectionType.DisplayPort, "DP", this);
|
eRoutingPortConnectionType.DisplayPort, "DP", this);
|
||||||
InputPorts.AddRange(new[] { hdmiIn1, hdmiIn2, hdmiIn3, hdmiIn4, dpIn });
|
InputPorts.AddRange(new[] { hdmiIn1, hdmiIn2, hdmiIn3, hdmiIn4, dpIn });
|
||||||
|
|
||||||
VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
|
VolumeLevelFeedback = new IntFeedback("volume", () => { return _FakeVolumeLevel; });
|
||||||
MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted);
|
MuteFeedback = new BoolFeedback("muteOn", () => _IsMuted);
|
||||||
|
|
||||||
WarmupTime = 10000;
|
WarmupTime = 10000;
|
||||||
CooldownTime = 10000;
|
CooldownTime = 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PowerOn method
|
/// PowerOn method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void PowerOn()
|
public override void PowerOn()
|
||||||
{
|
{
|
||||||
if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||||
{
|
{
|
||||||
_IsWarmingUp = true;
|
_IsWarmingUp = true;
|
||||||
IsWarmingUpFeedback.InvokeFireUpdate();
|
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||||
// Fake power-up cycle
|
// Fake power-up cycle
|
||||||
WarmupTimer = new CTimer(o =>
|
WarmupTimer = new CTimer(o =>
|
||||||
{
|
{
|
||||||
_IsWarmingUp = false;
|
_IsWarmingUp = false;
|
||||||
_PowerIsOn = true;
|
_PowerIsOn = true;
|
||||||
IsWarmingUpFeedback.InvokeFireUpdate();
|
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||||
PowerIsOnFeedback.InvokeFireUpdate();
|
PowerIsOnFeedback.InvokeFireUpdate();
|
||||||
}, WarmupTime);
|
}, WarmupTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PowerOff method
|
/// PowerOff method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void PowerOff()
|
public override void PowerOff()
|
||||||
{
|
{
|
||||||
// If a display has unreliable-power off feedback, just override this and
|
// If a display has unreliable-power off feedback, just override this and
|
||||||
// remove this check.
|
// remove this check.
|
||||||
if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||||
{
|
{
|
||||||
_IsCoolingDown = true;
|
_IsCoolingDown = true;
|
||||||
IsCoolingDownFeedback.InvokeFireUpdate();
|
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||||
// Fake cool-down cycle
|
// Fake cool-down cycle
|
||||||
CooldownTimer = new CTimer(o =>
|
CooldownTimer = new CTimer(o =>
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Cooldown timer ending", this);
|
Debug.LogMessage(LogEventLevel.Verbose, "Cooldown timer ending", this);
|
||||||
_IsCoolingDown = false;
|
_IsCoolingDown = false;
|
||||||
IsCoolingDownFeedback.InvokeFireUpdate();
|
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||||
_PowerIsOn = false;
|
_PowerIsOn = false;
|
||||||
PowerIsOnFeedback.InvokeFireUpdate();
|
PowerIsOnFeedback.InvokeFireUpdate();
|
||||||
}, CooldownTime);
|
}, CooldownTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PowerToggle method
|
/// PowerToggle method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void PowerToggle()
|
public override void PowerToggle()
|
||||||
{
|
{
|
||||||
if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
|
if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
|
||||||
PowerOff();
|
PowerOff();
|
||||||
else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
|
else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
|
||||||
PowerOn();
|
PowerOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ExecuteSwitch method
|
/// ExecuteSwitch method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void ExecuteSwitch(object selector)
|
public override void ExecuteSwitch(object selector)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "ExecuteSwitch: {0}", this, selector);
|
Debug.LogMessage(LogEventLevel.Verbose, "ExecuteSwitch: {0}", this, selector);
|
||||||
|
|
||||||
if (!_PowerIsOn)
|
if (!_PowerIsOn)
|
||||||
{
|
{
|
||||||
PowerOn();
|
PowerOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Inputs.Items.TryGetValue(selector.ToString(), out var input))
|
if (!Inputs.Items.TryGetValue(selector.ToString(), out var input))
|
||||||
return;
|
return;
|
||||||
@@ -190,7 +208,8 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Setting current input port to {inputPort}", this, inputPort);
|
Debug.LogMessage(LogEventLevel.Verbose, "Setting current input port to {inputPort}", this, inputPort);
|
||||||
CurrentInputPort = inputPort;
|
CurrentInputPort = inputPort;
|
||||||
} catch (Exception ex)
|
}
|
||||||
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(ex, "Error making switch: {Exception}", this, ex);
|
Debug.LogMessage(ex, "Error making switch: {Exception}", this, ex);
|
||||||
}
|
}
|
||||||
@@ -201,13 +220,13 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetInput(string selector)
|
public void SetInput(string selector)
|
||||||
{
|
{
|
||||||
ISelectableItem currentInput = null;
|
ISelectableItem currentInput = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
currentInput = Inputs.Items.SingleOrDefault(Inputs => Inputs.Value.IsSelected).Value;
|
currentInput = Inputs.Items.SingleOrDefault(Inputs => Inputs.Value.IsSelected).Value;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
|
|
||||||
if (currentInput != null)
|
if (currentInput != null)
|
||||||
@@ -216,12 +235,12 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
currentInput.IsSelected = false;
|
currentInput.IsSelected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Inputs.Items.TryGetValue(selector, out var input))
|
if (!Inputs.Items.TryGetValue(selector, out var input))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
input.IsSelected = true;
|
input.IsSelected = true;
|
||||||
|
|
||||||
Inputs.CurrentItem = selector;
|
Inputs.CurrentItem = selector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -232,37 +251,37 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IntFeedback VolumeLevelFeedback { get; private set; }
|
public IntFeedback VolumeLevelFeedback { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SetVolume method
|
/// SetVolume method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetVolume(ushort level)
|
public void SetVolume(ushort level)
|
||||||
{
|
{
|
||||||
_FakeVolumeLevel = level;
|
_FakeVolumeLevel = level;
|
||||||
VolumeLevelFeedback.InvokeFireUpdate();
|
VolumeLevelFeedback.InvokeFireUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MuteOn method
|
/// MuteOn method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void MuteOn()
|
public void MuteOn()
|
||||||
{
|
{
|
||||||
_IsMuted = true;
|
_IsMuted = true;
|
||||||
MuteFeedback.InvokeFireUpdate();
|
MuteFeedback.InvokeFireUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MuteOff method
|
/// MuteOff method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void MuteOff()
|
public void MuteOff()
|
||||||
{
|
{
|
||||||
_IsMuted = false;
|
_IsMuted = false;
|
||||||
MuteFeedback.InvokeFireUpdate();
|
MuteFeedback.InvokeFireUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the MuteFeedback
|
/// Gets or sets the MuteFeedback
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BoolFeedback MuteFeedback { get; private set; }
|
public BoolFeedback MuteFeedback { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -273,74 +292,77 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
/// VolumeUp method
|
/// VolumeUp method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void VolumeUp(bool pressRelease)
|
public void VolumeUp(bool pressRelease)
|
||||||
{
|
{
|
||||||
//while (pressRelease)
|
//while (pressRelease)
|
||||||
//{
|
//{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Down {0}", pressRelease);
|
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Down {0}", pressRelease);
|
||||||
if (pressRelease)
|
if (pressRelease)
|
||||||
{
|
{
|
||||||
var newLevel = _FakeVolumeLevel + VolumeInterval;
|
var newLevel = _FakeVolumeLevel + VolumeInterval;
|
||||||
SetVolume((ushort)newLevel);
|
SetVolume((ushort)newLevel);
|
||||||
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// VolumeDown method
|
/// VolumeDown method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void VolumeDown(bool pressRelease)
|
public void VolumeDown(bool pressRelease)
|
||||||
{
|
{
|
||||||
//while (pressRelease)
|
//while (pressRelease)
|
||||||
//{
|
//{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Up {0}", pressRelease);
|
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Up {0}", pressRelease);
|
||||||
if (pressRelease)
|
if (pressRelease)
|
||||||
{
|
{
|
||||||
var newLevel = _FakeVolumeLevel - VolumeInterval;
|
var newLevel = _FakeVolumeLevel - VolumeInterval;
|
||||||
SetVolume((ushort)newLevel);
|
SetVolume((ushort)newLevel);
|
||||||
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MuteToggle method
|
/// MuteToggle method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void MuteToggle()
|
public void MuteToggle()
|
||||||
{
|
{
|
||||||
_IsMuted = !_IsMuted;
|
_IsMuted = !_IsMuted;
|
||||||
MuteFeedback.InvokeFireUpdate();
|
MuteFeedback.InvokeFireUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// LinkToApi method
|
/// LinkToApi method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||||
{
|
{
|
||||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a MockDisplayFactory
|
/// Represents a MockDisplayFactory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MockDisplayFactory : EssentialsDeviceFactory<MockDisplay>
|
public class MockDisplayFactory : EssentialsDeviceFactory<MockDisplay>
|
||||||
{
|
{
|
||||||
public MockDisplayFactory()
|
/// <summary>
|
||||||
{
|
/// Initializes a new instance of the MockDisplayFactory class
|
||||||
TypeNames = new List<string>() { "mockdisplay" , "mockdisplay2" };
|
/// </summary>
|
||||||
}
|
public MockDisplayFactory()
|
||||||
|
{
|
||||||
|
TypeNames = new List<string>() { "mockdisplay", "mockdisplay2" };
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// BuildDevice method
|
/// BuildDevice method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Mock Display Device");
|
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Mock Display Device");
|
||||||
return new MockDisplay(dc.Key, dc.Name);
|
return new MockDisplay(dc.Key, dc.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Displays
|
namespace PepperDash.Essentials.Devices.Common.Displays
|
||||||
{
|
{
|
||||||
@@ -15,6 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
{
|
{
|
||||||
private Dictionary<string, ISelectableItem> _items;
|
private Dictionary<string, ISelectableItem> _items;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the collection of selectable items
|
||||||
|
/// </summary>
|
||||||
public Dictionary<string, ISelectableItem> Items
|
public Dictionary<string, ISelectableItem> Items
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -34,6 +33,9 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
|
|
||||||
private string _currentItem;
|
private string _currentItem;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the currently selected item
|
||||||
|
/// </summary>
|
||||||
public string CurrentItem
|
public string CurrentItem
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -51,7 +53,13 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the items collection is updated
|
||||||
|
/// </summary>
|
||||||
public event EventHandler ItemsUpdated;
|
public event EventHandler ItemsUpdated;
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the current item changes
|
||||||
|
/// </summary>
|
||||||
public event EventHandler CurrentItemChanged;
|
public event EventHandler CurrentItemChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +72,9 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
|
|
||||||
private bool _isSelected;
|
private bool _isSelected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether this input is selected
|
||||||
|
/// </summary>
|
||||||
public bool IsSelected
|
public bool IsSelected
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -91,8 +102,17 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when this item is updated
|
||||||
|
/// </summary>
|
||||||
public event EventHandler ItemUpdated;
|
public event EventHandler ItemUpdated;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the MockDisplayInput class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The input key</param>
|
||||||
|
/// <param name="name">The input name</param>
|
||||||
|
/// <param name="parent">The parent mock display</param>
|
||||||
public MockDisplayInput(string key, string name, MockDisplay parent)
|
public MockDisplayInput(string key, string name, MockDisplay parent)
|
||||||
{
|
{
|
||||||
Key = key;
|
Key = key;
|
||||||
@@ -107,7 +127,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
{
|
{
|
||||||
if (!_parent.PowerIsOnFeedback.BoolValue) _parent.PowerOn();
|
if (!_parent.PowerIsOnFeedback.BoolValue) _parent.PowerOn();
|
||||||
|
|
||||||
foreach(var input in _parent.Inputs.Items)
|
foreach (var input in _parent.Inputs.Items)
|
||||||
{
|
{
|
||||||
input.Value.IsSelected = input.Key == this.Key;
|
input.Value.IsSelected = input.Key == this.Key;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Converters;
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.CrestronIO;
|
using PepperDash.Essentials.Core.CrestronIO;
|
||||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
using PepperDash.Essentials.Devices.Common;
|
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Shades
|
namespace PepperDash.Essentials.Devices.Common.Shades
|
||||||
@@ -28,6 +25,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
ISwitchedOutput LowerRelay;
|
ISwitchedOutput LowerRelay;
|
||||||
ISwitchedOutput LatchedRelay;
|
ISwitchedOutput LatchedRelay;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the InUpPosition
|
||||||
|
/// </summary>
|
||||||
public bool InUpPosition
|
public bool InUpPosition
|
||||||
{
|
{
|
||||||
get { return _isInUpPosition; }
|
get { return _isInUpPosition; }
|
||||||
@@ -41,10 +41,12 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool _isInUpPosition { get; set; }
|
private bool _isInUpPosition { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Type
|
/// Gets or sets the Type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public eScreenLiftControlType Type { get; private set; }
|
public eScreenLiftControlType Type { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Mode
|
/// Gets or sets the Mode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -54,13 +56,20 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
/// Gets or sets the DisplayDeviceKey
|
/// Gets or sets the DisplayDeviceKey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DisplayDeviceKey { get; private set; }
|
public string DisplayDeviceKey { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the IsInUpPosition
|
/// Gets or sets the IsInUpPosition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BoolFeedback IsInUpPosition { get; private set; }
|
public BoolFeedback IsInUpPosition { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event that fires when the position changes
|
||||||
|
/// </summary>
|
||||||
public event EventHandler<EventArgs> PositionChanged;
|
public event EventHandler<EventArgs> PositionChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for ScreenLiftController
|
||||||
|
/// </summary>
|
||||||
public ScreenLiftController(string key, string name, ScreenLiftControllerConfigProperties config)
|
public ScreenLiftController(string key, string name, ScreenLiftControllerConfigProperties config)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
@@ -69,7 +78,7 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
Mode = Config.Mode;
|
Mode = Config.Mode;
|
||||||
Type = Config.Type;
|
Type = Config.Type;
|
||||||
|
|
||||||
IsInUpPosition = new BoolFeedback(() => _isInUpPosition);
|
IsInUpPosition = new BoolFeedback("isInUpPosition", () => _isInUpPosition);
|
||||||
|
|
||||||
switch (Mode)
|
switch (Mode)
|
||||||
{
|
{
|
||||||
@@ -206,14 +215,14 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attempts to get the port on teh specified device from config
|
/// Attempts to get the port on teh specified device from config
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="relayConfig"></param>
|
/// <param name="relayKey"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
ISwitchedOutput GetSwitchedOutputFromDevice(string relayKey)
|
ISwitchedOutput GetSwitchedOutputFromDevice(string relayKey)
|
||||||
{
|
{
|
||||||
var portDevice = DeviceManager.GetDeviceForKey(relayKey);
|
var portDevice = DeviceManager.GetDeviceForKey(relayKey);
|
||||||
if (portDevice != null)
|
if (portDevice != null)
|
||||||
{
|
{
|
||||||
return (portDevice as ISwitchedOutput);
|
return portDevice as ISwitchedOutput;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -238,58 +247,14 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a ScreenLiftControllerConfigProperties
|
|
||||||
/// </summary>
|
|
||||||
public class ScreenLiftControllerConfigProperties
|
|
||||||
{
|
|
||||||
[JsonProperty("displayDeviceKey")]
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the DisplayDeviceKey
|
|
||||||
/// </summary>
|
|
||||||
public string DisplayDeviceKey { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("type")]
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the Type
|
|
||||||
/// </summary>
|
|
||||||
public eScreenLiftControlType Type { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("mode")]
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the Mode
|
|
||||||
/// </summary>
|
|
||||||
public eScreenLiftControlMode Mode { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("relays")]
|
|
||||||
public Dictionary<string,ScreenLiftRelaysConfig> Relays { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a ScreenLiftRelaysConfig
|
|
||||||
/// </summary>
|
|
||||||
public class ScreenLiftRelaysConfig
|
|
||||||
{
|
|
||||||
[JsonProperty("deviceKey")]
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the DeviceKey
|
|
||||||
/// </summary>
|
|
||||||
public string DeviceKey { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("pulseTimeInMs")]
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the PulseTimeInMs
|
|
||||||
/// </summary>
|
|
||||||
public int PulseTimeInMs { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a ScreenLiftControllerFactory
|
/// Represents a ScreenLiftControllerFactory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ScreenLiftControllerFactory : EssentialsDeviceFactory<RelayControlledShade>
|
public class ScreenLiftControllerFactory : EssentialsDeviceFactory<RelayControlledShade>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for ScreenLiftControllerFactory
|
||||||
|
/// </summary>
|
||||||
public ScreenLiftControllerFactory()
|
public ScreenLiftControllerFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string>() { "screenliftcontroller" };
|
TypeNames = new List<string>() { "screenliftcontroller" };
|
||||||
@@ -307,13 +272,4 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
return new ScreenLiftController(dc.Key, dc.Name, props);
|
return new ScreenLiftController(dc.Key, dc.Name, props);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Enumeration of eScreenLiftControlMode values
|
|
||||||
/// </summary>
|
|
||||||
public enum eScreenLiftControlMode
|
|
||||||
{
|
|
||||||
momentary,
|
|
||||||
latched
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Devices.Common.Shades
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a ScreenLiftControllerConfigProperties
|
||||||
|
/// </summary>
|
||||||
|
public class ScreenLiftControllerConfigProperties
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the DisplayDeviceKey
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("displayDeviceKey")]
|
||||||
|
public string DisplayDeviceKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Type
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("type")]
|
||||||
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
|
public eScreenLiftControlType Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Mode
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("mode")]
|
||||||
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
|
public eScreenLiftControlMode Mode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Relays
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("relays")]
|
||||||
|
public Dictionary<string, ScreenLiftRelaysConfig> Relays { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Devices.Common.Shades
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a ScreenLiftRelaysConfig
|
||||||
|
/// </summary>
|
||||||
|
public class ScreenLiftRelaysConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the DeviceKey
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("deviceKey")]
|
||||||
|
public string DeviceKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the PulseTimeInMs
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("pulseTimeInMs")]
|
||||||
|
public int PulseTimeInMs { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
using System;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Devices.Common.Displays
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Abstract base class for two-way display devices that provide feedback capabilities.
|
||||||
|
/// Extends DisplayBase with routing feedback and power control feedback functionality.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets feedback for the current input selection on the display.
|
||||||
|
/// </summary>
|
||||||
|
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Abstract function that must be implemented by derived classes to provide the current input feedback value.
|
||||||
|
/// Must be implemented by concrete sub-classes.
|
||||||
|
/// </summary>
|
||||||
|
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets feedback indicating whether the display is currently powered on.
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Abstract function that must be implemented by derived classes to provide the power state feedback value.
|
||||||
|
/// Must be implemented by concrete sub-classes.
|
||||||
|
/// </summary>
|
||||||
|
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the default mock display instance for testing and development purposes.
|
||||||
|
/// </summary>
|
||||||
|
public static MockDisplay DefaultDisplay
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_DefaultDisplay == null)
|
||||||
|
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||||
|
return _DefaultDisplay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static MockDisplay _DefaultDisplay;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the TwoWayDisplayBase class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The unique key identifier for this display device.</param>
|
||||||
|
/// <param name="name">The friendly name for this display device.</param>
|
||||||
|
public TwoWayDisplayBase(string key, string name)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
CurrentInputFeedback = new StringFeedback("currentInput", CurrentInputFeedbackFunc);
|
||||||
|
|
||||||
|
WarmupTime = 7000;
|
||||||
|
CooldownTime = 15000;
|
||||||
|
|
||||||
|
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||||
|
|
||||||
|
Feedbacks.Add(CurrentInputFeedback);
|
||||||
|
Feedbacks.Add(PowerIsOnFeedback);
|
||||||
|
|
||||||
|
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (UsageTracker != null)
|
||||||
|
{
|
||||||
|
if (PowerIsOnFeedback.BoolValue)
|
||||||
|
UsageTracker.StartDeviceUsage();
|
||||||
|
else
|
||||||
|
UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when a numeric switch change occurs on the display.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raise an event when the status of a switch object changes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||||
|
protected void OnSwitchChange(RoutingNumericEventArgs e)
|
||||||
|
{
|
||||||
|
NumericSwitchChange?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
namespace PepperDash.Essentials.Devices.Common.Shades
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enumeration of eScreenLiftControlMode values
|
||||||
|
/// </summary>
|
||||||
|
public enum eScreenLiftControlMode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Momentary control mode for screen lift
|
||||||
|
/// </summary>
|
||||||
|
momentary,
|
||||||
|
/// <summary>
|
||||||
|
/// Latched control mode for screen lift
|
||||||
|
/// </summary>
|
||||||
|
latched
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +1,26 @@
|
|||||||
using PepperDash.Core;
|
using System.Collections.Generic;
|
||||||
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Generic
|
namespace PepperDash.Essentials.Devices.Common.Generic
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a GenericSink
|
/// Represents a GenericSink
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericSink : EssentialsDevice, IRoutingSinkWithInputPort
|
public class GenericSink : EssentialsDevice, IRoutingSinkWithSwitchingWithInputPort
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the GenericSink class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The device key</param>
|
||||||
|
/// <param name="name">The device name</param>
|
||||||
public GenericSink(string key, string name) : base(key, name)
|
public GenericSink(string key, string name) : base(key, name)
|
||||||
{
|
{
|
||||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||||
|
|
||||||
var inputPort = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
|
var inputPort = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo | eRoutingSignalType.SecondaryAudio, eRoutingPortConnectionType.Hdmi, null, this);
|
||||||
|
|
||||||
InputPorts.Add(inputPort);
|
InputPorts.Add(inputPort);
|
||||||
}
|
}
|
||||||
@@ -35,10 +39,12 @@ namespace PepperDash.Essentials.Devices.Common.Generic
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the CurrentSourceInfo
|
/// Gets or sets the CurrentSourceInfo
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SourceListItem CurrentSourceInfo {
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
get => _currentSource;
|
get => _currentSource;
|
||||||
set {
|
set
|
||||||
if(value == _currentSource)
|
{
|
||||||
|
if (value == _currentSource)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -51,9 +57,24 @@ namespace PepperDash.Essentials.Devices.Common.Generic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current input port
|
||||||
|
/// </summary>
|
||||||
public RoutingInputPort CurrentInputPort => InputPorts[0];
|
public RoutingInputPort CurrentInputPort => InputPorts[0];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when the current source changes
|
||||||
|
/// </summary>
|
||||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event InputChangedEventHandler InputChanged;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void ExecuteSwitch(object inputSelector)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -61,6 +82,9 @@ namespace PepperDash.Essentials.Devices.Common.Generic
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericSinkFactory : EssentialsDeviceFactory<GenericSink>
|
public class GenericSinkFactory : EssentialsDeviceFactory<GenericSink>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the GenericSinkFactory class
|
||||||
|
/// </summary>
|
||||||
public GenericSinkFactory()
|
public GenericSinkFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string>() { "genericsink", "genericdestination" };
|
TypeNames = new List<string>() { "genericsink", "genericdestination" };
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
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.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
@@ -13,38 +7,43 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common
|
namespace PepperDash.Essentials.Devices.Common
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a GenericSource
|
/// Represents a GenericSource
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IUsageTracking
|
public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IUsageTracking
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the DisplayUiType
|
/// Gets or sets the DisplayUiType
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } }
|
public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the GenericSource class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The device key</param>
|
||||||
|
/// <param name="name">The device name</param>
|
||||||
public GenericSource(string key, string name)
|
public GenericSource(string key, string name)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
|
|
||||||
AnyOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
AnyOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||||
eRoutingPortConnectionType.Hdmi, null, this);
|
eRoutingPortConnectionType.Hdmi, null, this);
|
||||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { AnyOut };
|
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { AnyOut };
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IRoutingOutputs Members
|
#region IRoutingOutputs Members
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the AnyOut
|
/// Gets or sets the AnyOut
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RoutingOutputPort AnyOut { get; private set; }
|
public RoutingOutputPort AnyOut { get; private set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the OutputPorts
|
/// Gets or sets the OutputPorts
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IUsageTracking Members
|
#region IUsageTracking Members
|
||||||
|
|
||||||
@@ -54,13 +53,16 @@ namespace PepperDash.Essentials.Devices.Common
|
|||||||
public UsageTracking UsageTracker { get; set; }
|
public UsageTracking UsageTracker { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a GenericSourceFactory
|
/// Represents a GenericSourceFactory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericSourceFactory : EssentialsDeviceFactory<GenericSource>
|
public class GenericSourceFactory : EssentialsDeviceFactory<GenericSource>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the GenericSourceFactory class
|
||||||
|
/// </summary>
|
||||||
public GenericSourceFactory()
|
public GenericSourceFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string>() { "genericsource" };
|
TypeNames = new List<string>() { "genericsource" };
|
||||||
|
|||||||
@@ -3,9 +3,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
using Crestron.SimplSharpPro;
|
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
@@ -16,134 +13,165 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Lighting
|
namespace PepperDash.Essentials.Devices.Common.Lighting
|
||||||
{
|
{
|
||||||
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
|
|
||||||
{
|
|
||||||
#region ILightingScenes Members
|
|
||||||
|
|
||||||
public event EventHandler<LightingSceneChangeEventArgs> LightingSceneChange;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the LightingScenes
|
|
||||||
/// </summary>
|
|
||||||
public List<LightingScene> LightingScenes { get; protected set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the CurrentLightingScene
|
|
||||||
/// </summary>
|
|
||||||
public LightingScene CurrentLightingScene { get; protected set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the CurrentLightingSceneFeedback
|
/// Base class for lighting devices that support scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IntFeedback CurrentLightingSceneFeedback { get; protected set; }
|
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
|
||||||
|
{
|
||||||
|
#region ILightingScenes Members
|
||||||
|
|
||||||
#endregion
|
/// <summary>
|
||||||
|
/// Event fired when lighting scene changes
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<LightingSceneChangeEventArgs> LightingSceneChange;
|
||||||
|
|
||||||
protected LightingBase(string key, string name)
|
/// <summary>
|
||||||
: base(key, name)
|
/// Gets or sets the LightingScenes
|
||||||
{
|
/// </summary>
|
||||||
LightingScenes = new List<LightingScene>();
|
public List<LightingScene> LightingScenes { get; protected set; }
|
||||||
|
|
||||||
CurrentLightingScene = new LightingScene();
|
/// <summary>
|
||||||
//CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); });
|
/// Gets or sets the CurrentLightingScene
|
||||||
}
|
/// </summary>
|
||||||
|
public LightingScene CurrentLightingScene { get; protected set; }
|
||||||
|
|
||||||
public abstract void SelectScene(LightingScene scene);
|
/// <summary>
|
||||||
|
/// Gets or sets the CurrentLightingSceneFeedback
|
||||||
|
/// </summary>
|
||||||
|
public IntFeedback CurrentLightingSceneFeedback { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
#endregion
|
||||||
/// SimulateSceneSelect method
|
|
||||||
/// </summary>
|
|
||||||
public void SimulateSceneSelect(string sceneName)
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "Simulating selection of scene '{0}'", sceneName);
|
|
||||||
|
|
||||||
var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName));
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the LightingBase class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The device key</param>
|
||||||
|
/// <param name="name">The device name</param>
|
||||||
|
protected LightingBase(string key, string name)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
LightingScenes = new List<LightingScene>();
|
||||||
|
|
||||||
if (scene != null)
|
CurrentLightingScene = new LightingScene();
|
||||||
{
|
//CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); });
|
||||||
CurrentLightingScene = scene;
|
}
|
||||||
OnLightingSceneChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the IsActive property on each scene and fires the LightingSceneChange event
|
/// Selects the specified lighting scene
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected void OnLightingSceneChange()
|
/// <param name="scene">The lighting scene to select</param>
|
||||||
{
|
public abstract void SelectScene(LightingScene scene);
|
||||||
foreach (var scene in LightingScenes)
|
|
||||||
{
|
|
||||||
if (scene == CurrentLightingScene)
|
|
||||||
scene.IsActive = true;
|
|
||||||
|
|
||||||
else
|
/// <summary>
|
||||||
scene.IsActive = false;
|
/// SimulateSceneSelect method
|
||||||
}
|
/// </summary>
|
||||||
LightingSceneChange?.Invoke(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
|
public void SimulateSceneSelect(string sceneName)
|
||||||
}
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Debug, this, "Simulating selection of scene '{0}'", sceneName);
|
||||||
|
|
||||||
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
|
var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName));
|
||||||
string joinMapKey, EiscApiAdvanced bridge)
|
|
||||||
{
|
|
||||||
var joinMap = new GenericLightingJoinMap(joinStart);
|
|
||||||
|
|
||||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
if (scene != null)
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
|
||||||
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(joinMapSerialized);
|
|
||||||
|
|
||||||
if (bridge != null)
|
|
||||||
{
|
|
||||||
bridge.AddJoinMap(Key, joinMap);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return LinkLightingToApi(lightingDevice, trilist, joinMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap)
|
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
CurrentLightingScene = scene;
|
||||||
|
OnLightingSceneChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
|
/// <summary>
|
||||||
|
/// Sets the IsActive property on each scene and fires the LightingSceneChange event
|
||||||
|
/// </summary>
|
||||||
|
protected void OnLightingSceneChange()
|
||||||
|
{
|
||||||
|
foreach (var scene in LightingScenes)
|
||||||
|
{
|
||||||
|
if (scene == CurrentLightingScene)
|
||||||
|
scene.IsActive = true;
|
||||||
|
|
||||||
// GenericLighitng Actions & FeedBack
|
else
|
||||||
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
|
scene.IsActive = false;
|
||||||
|
}
|
||||||
|
LightingSceneChange?.Invoke(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
|
||||||
|
}
|
||||||
|
|
||||||
var sceneIndex = 0;
|
/// <summary>
|
||||||
|
/// Links the lighting device to API with join map configuration
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lightingDevice">The lighting device to link</param>
|
||||||
|
/// <param name="trilist">The trilist to link to</param>
|
||||||
|
/// <param name="joinStart">The starting join number</param>
|
||||||
|
/// <param name="joinMapKey">The join map key</param>
|
||||||
|
/// <param name="bridge">The EISC API bridge</param>
|
||||||
|
/// <returns>The configured join map</returns>
|
||||||
|
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
|
||||||
|
string joinMapKey, EiscApiAdvanced bridge)
|
||||||
|
{
|
||||||
|
var joinMap = new GenericLightingJoinMap(joinStart);
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
if (bridge != null)
|
||||||
|
{
|
||||||
|
bridge.AddJoinMap(Key, joinMap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return LinkLightingToApi(lightingDevice, trilist, joinMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Links the lighting device to API using an existing join map
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lightingDevice">The lighting device to link</param>
|
||||||
|
/// <param name="trilist">The trilist to link to</param>
|
||||||
|
/// <param name="joinMap">The join map to use</param>
|
||||||
|
/// <returns>The join map used for linking</returns>
|
||||||
|
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
|
||||||
|
|
||||||
|
// GenericLighitng Actions & FeedBack
|
||||||
|
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
|
||||||
|
|
||||||
|
var sceneIndex = 0;
|
||||||
|
foreach (var scene in lightingDevice.LightingScenes)
|
||||||
|
{
|
||||||
|
var index = sceneIndex;
|
||||||
|
|
||||||
|
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + index), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[index]));
|
||||||
|
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)]);
|
||||||
|
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
|
||||||
|
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
|
||||||
|
|
||||||
|
sceneIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
trilist.OnlineStatusChange += (sender, args) =>
|
||||||
|
{
|
||||||
|
if (!args.DeviceOnLine) return;
|
||||||
|
|
||||||
|
sceneIndex = 0;
|
||||||
foreach (var scene in lightingDevice.LightingScenes)
|
foreach (var scene in lightingDevice.LightingScenes)
|
||||||
{
|
{
|
||||||
var index = sceneIndex;
|
var index = sceneIndex;
|
||||||
|
|
||||||
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + index), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[index]));
|
|
||||||
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)]);
|
|
||||||
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
|
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
|
||||||
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
|
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
|
||||||
|
scene.IsActiveFeedback.FireUpdate();
|
||||||
|
|
||||||
sceneIndex++;
|
sceneIndex++;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
trilist.OnlineStatusChange += (sender, args) =>
|
return joinMap;
|
||||||
{
|
|
||||||
if (!args.DeviceOnLine) return;
|
|
||||||
|
|
||||||
sceneIndex = 0;
|
|
||||||
foreach (var scene in lightingDevice.LightingScenes)
|
|
||||||
{
|
|
||||||
var index = sceneIndex;
|
|
||||||
|
|
||||||
trilist.StringInput[(uint) (joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
|
|
||||||
trilist.BooleanInput[(uint) (joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
|
|
||||||
scene.IsActiveFeedback.FireUpdate();
|
|
||||||
|
|
||||||
sceneIndex++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return joinMap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -9,10 +9,20 @@ namespace PepperDash.Essentials.Devices.Common.Room
|
|||||||
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IHasDefaultDisplay, IHasCurrentVolumeControls, IRoomOccupancy,
|
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IHasDefaultDisplay, IHasCurrentVolumeControls, IRoomOccupancy,
|
||||||
IEmergency, IMicrophonePrivacy
|
IEmergency, IMicrophonePrivacy
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether to exclude this room from global functions
|
||||||
|
/// </summary>
|
||||||
bool ExcludeFromGlobalFunctions { get; }
|
bool ExcludeFromGlobalFunctions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs the route action for the given routeKey and sourceListKey
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey">The route key</param>
|
||||||
void RunRouteAction(string routeKey);
|
void RunRouteAction(string routeKey);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the PropertiesConfig
|
||||||
|
/// </summary>
|
||||||
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
|
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,18 +12,40 @@ namespace PepperDash.Essentials.Devices.Common.Room
|
|||||||
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback,
|
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback,
|
||||||
IRoomOccupancy, IEmergency, IMicrophonePrivacy
|
IRoomOccupancy, IEmergency, IMicrophonePrivacy
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the PropertiesConfig
|
||||||
|
/// </summary>
|
||||||
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
|
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether to exclude this room from global functions
|
||||||
|
/// </summary>
|
||||||
bool ExcludeFromGlobalFunctions { get; }
|
bool ExcludeFromGlobalFunctions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs the route action for the given routeKey and sourceListKey
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey">The route key</param>
|
||||||
void RunRouteAction(string routeKey);
|
void RunRouteAction(string routeKey);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ScheduleSource
|
||||||
|
/// </summary>
|
||||||
IHasScheduleAwareness ScheduleSource { get; }
|
IHasScheduleAwareness ScheduleSource { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the InCallFeedback
|
||||||
|
/// </summary>
|
||||||
new BoolFeedback InCallFeedback { get; }
|
new BoolFeedback InCallFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the PrivacyModeIsOnFeedback
|
||||||
|
/// </summary>
|
||||||
new BoolFeedback PrivacyModeIsOnFeedback { get; }
|
new BoolFeedback PrivacyModeIsOnFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the DefaultCodecRouteString
|
||||||
|
/// </summary>
|
||||||
string DefaultCodecRouteString { get; }
|
string DefaultCodecRouteString { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
using PepperDash.Essentials.Room.Config;
|
using PepperDash.Essentials.Room.Config;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Room
|
namespace PepperDash.Essentials.Devices.Common.Room
|
||||||
{
|
{
|
||||||
@@ -12,6 +7,9 @@ namespace PepperDash.Essentials.Devices.Common.Room
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IEssentialsRoomPropertiesConfig
|
public interface IEssentialsRoomPropertiesConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the PropertiesConfig
|
||||||
|
/// </summary>
|
||||||
EssentialsRoomPropertiesConfig PropertiesConfig { get; }
|
EssentialsRoomPropertiesConfig PropertiesConfig { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using PepperDash.Essentials.Core;
|
using System.Collections.Generic;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Displays;
|
||||||
using PepperDash.Essentials.Room.Config;
|
using PepperDash.Essentials.Room.Config;
|
||||||
using System.Collections.Generic;
|
|
||||||
using TwoWayDisplayBase = PepperDash.Essentials.Devices.Common.Displays.TwoWayDisplayBase;
|
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Room
|
namespace PepperDash.Essentials.Devices.Common.Room
|
||||||
@@ -11,15 +11,31 @@ namespace PepperDash.Essentials.Devices.Common.Room
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IEssentialsTechRoom
|
/// Defines the contract for IEssentialsTechRoom
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IEssentialsTechRoom:IEssentialsRoom, ITvPresetsProvider,IBridgeAdvanced,IRunDirectRouteAction
|
public interface IEssentialsTechRoom : IEssentialsRoom, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the PropertiesConfig
|
||||||
|
/// </summary>
|
||||||
EssentialsTechRoomConfig PropertiesConfig { get; }
|
EssentialsTechRoomConfig PropertiesConfig { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Tuners
|
||||||
|
/// </summary>
|
||||||
Dictionary<string, IRSetTopBoxBase> Tuners { get; }
|
Dictionary<string, IRSetTopBoxBase> Tuners { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Displays
|
||||||
|
/// </summary>
|
||||||
Dictionary<string, TwoWayDisplayBase> Displays { get; }
|
Dictionary<string, TwoWayDisplayBase> Displays { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Powers on the room
|
||||||
|
/// </summary>
|
||||||
void RoomPowerOn();
|
void RoomPowerOn();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Powers off the room
|
||||||
|
/// </summary>
|
||||||
void RoomPowerOff();
|
void RoomPowerOff();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Devices.Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a IRSetTopBoxBaseFactory
|
||||||
|
/// </summary>
|
||||||
|
public class IRSetTopBoxBaseFactory : EssentialsDeviceFactory<IRSetTopBoxBase>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="IRSetTopBoxBaseFactory"/> class
|
||||||
|
/// </summary>
|
||||||
|
public IRSetTopBoxBaseFactory()
|
||||||
|
{
|
||||||
|
TypeNames = new List<string>() { "settopbox" };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// BuildDevice method
|
||||||
|
/// </summary>
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new SetTopBox Device");
|
||||||
|
var irCont = IRPortHelper.GetIrOutputPortController(dc);
|
||||||
|
var config = dc.Properties.ToObject<SetTopBoxPropertiesConfig>();
|
||||||
|
var stb = new IRSetTopBoxBase(dc.Key, dc.Name, irCont, config);
|
||||||
|
|
||||||
|
var listName = dc.Properties.Value<string>("presetsList");
|
||||||
|
if (listName != null)
|
||||||
|
stb.LoadPresets(listName);
|
||||||
|
return stb;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
using PepperDash.Core;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
using PepperDash.Core;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common
|
namespace PepperDash.Essentials.Devices.Common
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string StopOrPresetButtonLabel { get; set; }
|
public string StopOrPresetButtonLabel { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the RelayControlledShade class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The device key</param>
|
||||||
|
/// <param name="name">The device name</param>
|
||||||
|
/// <param name="config">The relay controlled shade configuration</param>
|
||||||
public RelayControlledShade(string key, string name, RelayControlledShadeConfigProperties config)
|
public RelayControlledShade(string key, string name, RelayControlledShadeConfigProperties config)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
@@ -157,6 +163,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class RelayControlledShadeFactory : EssentialsDeviceFactory<RelayControlledShade>
|
public class RelayControlledShadeFactory : EssentialsDeviceFactory<RelayControlledShade>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the RelayControlledShadeFactory class
|
||||||
|
/// </summary>
|
||||||
public RelayControlledShadeFactory()
|
public RelayControlledShadeFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string>() { "relaycontrolledshade" };
|
TypeNames = new List<string>() { "relaycontrolledshade" };
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
using PepperDash.Essentials.Core.Shades;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core.Shades;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Shades
|
namespace PepperDash.Essentials.Devices.Common.Shades
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for shade devices
|
||||||
|
/// </summary>
|
||||||
public abstract class ShadeBase : EssentialsDevice, IShadesOpenCloseStop
|
public abstract class ShadeBase : EssentialsDevice, IShadesOpenCloseStop
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the ShadeBase class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The device key</param>
|
||||||
|
/// <param name="name">The device name</param>
|
||||||
public ShadeBase(string key, string name)
|
public ShadeBase(string key, string name)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
@@ -13,8 +21,17 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
|
|
||||||
#region iShadesOpenClose Members
|
#region iShadesOpenClose Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the shade
|
||||||
|
/// </summary>
|
||||||
public abstract void Open();
|
public abstract void Open();
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the shade
|
||||||
|
/// </summary>
|
||||||
public abstract void Stop();
|
public abstract void Stop();
|
||||||
|
/// <summary>
|
||||||
|
/// Closes the shade
|
||||||
|
/// </summary>
|
||||||
public abstract void Close();
|
public abstract void Close();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -14,8 +14,17 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
{
|
{
|
||||||
ShadeControllerConfigProperties Config;
|
ShadeControllerConfigProperties Config;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the collection of shades controlled by this controller
|
||||||
|
/// </summary>
|
||||||
public List<IShadesOpenCloseStop> Shades { get; private set; }
|
public List<IShadesOpenCloseStop> Shades { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the ShadeController class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The device key</param>
|
||||||
|
/// <param name="name">The device name</param>
|
||||||
|
/// <param name="config">The shade controller configuration</param>
|
||||||
public ShadeController(string key, string name, ShadeControllerConfigProperties config)
|
public ShadeController(string key, string name, ShadeControllerConfigProperties config)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
@@ -76,6 +85,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ShadeControllerFactory : EssentialsDeviceFactory<ShadeController>
|
public class ShadeControllerFactory : EssentialsDeviceFactory<ShadeController>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the ShadeControllerFactory class
|
||||||
|
/// </summary>
|
||||||
public ShadeControllerFactory()
|
public ShadeControllerFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string>() { "shadecontroller" };
|
TypeNames = new List<string>() { "shadecontroller" };
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user