mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-10 10:15:01 +00:00
Compare commits
228 Commits
feature/un
...
v2.25.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0764685c51 | ||
|
|
1404899342 | ||
|
|
a4759c3e67 | ||
|
|
a1029cd7c7 | ||
|
|
b1a5136ec6 | ||
|
|
a7c4e2fd60 | ||
|
|
4fa7a42330 | ||
|
|
9bad3ae21b | ||
|
|
3fb30d5561 | ||
|
|
57cd77f019 | ||
|
|
7f2bb078c8 | ||
|
|
316bb849b4 | ||
|
|
a983e2c87f | ||
|
|
babb9a77df | ||
|
|
7629921113 | ||
|
|
3878c85a7a | ||
|
|
7ad8218af0 | ||
|
|
0c4aec14d1 | ||
|
|
7d3f871460 | ||
|
|
78c9381108 | ||
|
|
a7ff2e8903 | ||
|
|
ae0b2fe086 | ||
|
|
bd11c827da | ||
|
|
7ea1efbabf | ||
|
|
9d6aaa2a0e | ||
|
|
53e7a30224 | ||
|
|
39c1f60a4d | ||
|
|
2cc37a4e40 | ||
|
|
076e5dfa9d | ||
|
|
092896bb25 | ||
|
|
7c8f0586e6 | ||
|
|
c5b0872a4c | ||
|
|
a7b88ec38d | ||
|
|
210b398a13 | ||
|
|
bce1e3610e | ||
|
|
6a33e7c99d | ||
|
|
2048e3f65d | ||
|
|
81df2738de | ||
|
|
08fbec416f | ||
|
|
7594b22096 | ||
|
|
d1babf6b9b | ||
|
|
2187c9fb0d | ||
|
|
a5e6059160 | ||
|
|
9ef4aedcce | ||
|
|
f7c7160bf0 | ||
|
|
dbf5740841 | ||
|
|
c07e099a79 | ||
|
|
06cb508f3a | ||
|
|
e93b5b34cc | ||
|
|
4f5d4ef87a | ||
|
|
636da8cc8c | ||
|
|
5de1e2d7bb | ||
|
|
03bbb84894 | ||
|
|
d17394cdd7 | ||
|
|
8467afde38 | ||
|
|
5c016fb4b8 | ||
|
|
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 | ||
|
|
419177ccd5 | ||
|
|
bd01e2bacc | ||
|
|
2928c5cf94 | ||
|
|
82b5dc96c1 | ||
|
|
37cea8a11c | ||
|
|
a3f0901fa0 | ||
|
|
f91f435768 | ||
|
|
5120b2b574 | ||
|
|
7c90027578 | ||
|
|
bb694b4200 | ||
|
|
087d0a1149 | ||
|
|
4747c16b02 | ||
|
|
aa4d241dde | ||
|
|
9fc5586531 | ||
|
|
d33fd56529 | ||
|
|
8fc4d21f02 | ||
|
|
6d93662b31 | ||
|
|
11b190e76f | ||
|
|
df03a71cbc | ||
|
|
72e67a1c4c | ||
|
|
f8728b6825 | ||
|
|
d9ef8a2289 | ||
|
|
278408a3bc | ||
|
|
fd70377c7f | ||
|
|
06341b14f3 | ||
|
|
d7f9c74b2f | ||
|
|
5921b5dbb0 | ||
|
|
ba0de5128f | ||
|
|
b0a090062f | ||
|
|
9c0cab8218 | ||
|
|
c0af637108 | ||
|
|
9c9eaea928 | ||
|
|
9de94bd65f | ||
|
|
ff46fb8f29 | ||
|
|
d9243def30 | ||
|
|
258699fbcd | ||
|
|
738504e9fc | ||
|
|
cae1bbd6e6 | ||
|
|
dea4407e3e | ||
|
|
ab08a546f7 | ||
|
|
ef98d47792 | ||
|
|
c05976ee60 | ||
|
|
4ca1031bef | ||
|
|
6d61c4525e | ||
|
|
3db274ace5 | ||
|
|
f0f708294c | ||
|
|
a00d186c62 | ||
|
|
51da668dfd | ||
|
|
d2b7400039 | ||
|
|
2424838b7f | ||
|
|
9556edc064 | ||
|
|
f9088691fd | ||
|
|
e40b6a8b4c | ||
|
|
c3b39a87da | ||
|
|
06dc0e947e | ||
|
|
147997f460 | ||
|
|
49abec5eea | ||
|
|
6830efe42a | ||
|
|
d013068a0c | ||
|
|
52916d29f4 | ||
|
|
19e8489166 | ||
|
|
fe33443b25 | ||
|
|
8cf195b262 | ||
|
|
40406b797d | ||
|
|
65bc408ebf | ||
|
|
9d49fb8357 | ||
|
|
fb7797dac7 | ||
|
|
574f5f6dc9 | ||
|
|
e49c69a12f | ||
|
|
7889cba196 | ||
|
|
033aa1f3dd | ||
|
|
9b6c2d80ea | ||
|
|
a0fc731701 | ||
|
|
f2d0dca7b8 | ||
|
|
ab4e85d081 | ||
|
|
47017da527 | ||
|
|
4f0d464ba4 | ||
|
|
0107422507 | ||
|
|
1a366790e7 | ||
|
|
97448f4f0f | ||
|
|
cf3ece4237 | ||
|
|
bb4b2f88b6 | ||
|
|
808e8042a7 | ||
|
|
0bc4388bfd | ||
|
|
dbc132c0da | ||
|
|
5bb0ab2626 | ||
|
|
27bf36c58c | ||
|
|
ce886aea63 | ||
|
|
ef920bf54c | ||
|
|
88466818ce | ||
|
|
0871a902e1 | ||
|
|
a031424752 | ||
|
|
fd1ba345aa | ||
|
|
e03874a7a9 | ||
|
|
2efab4f196 | ||
|
|
a41aba1904 | ||
|
|
d0ca6721f5 |
13
.config/dotnet-tools.json
Normal file
13
.config/dotnet-tools.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"isRoot": true,
|
||||||
|
"tools": {
|
||||||
|
"csharpier": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"commands": [
|
||||||
|
"csharpier"
|
||||||
|
],
|
||||||
|
"rollForward": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -395,3 +395,5 @@ essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/Pepp
|
|||||||
_site/
|
_site/
|
||||||
api/
|
api/
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
|
/._PepperDash.Essentials.4Series.sln
|
||||||
|
dotnet
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>2.4.0-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>
|
||||||
|
|||||||
@@ -23,23 +23,32 @@
|
|||||||
<FileName>$(TargetDir)$(TargetName).$(Version).$(TargetFramework).cpz</FileName>
|
<FileName>$(TargetDir)$(TargetName).$(Version).$(TargetFramework).cpz</FileName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Target Name="DeleteCLZ" BeforeTargets="PreBuildEvent" Condition="$(ProjectType) == 'Library' And $(TargetDir) != '' And Exists($(FileName))">
|
<Target Name="DeleteCLZ" BeforeTargets="CoreBuild" Condition="$(ProjectType) == 'Library' And $(TargetDir) != ''">
|
||||||
<Delete Files="$(TargetDir)$(TargetName).$(Version).$(TargetFramework).clz">
|
<ItemGroup>
|
||||||
|
<OldCLZFiles Include="$(TargetDir)$(TargetName).*.$(TargetFramework).clz" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Delete Files="@(OldCLZFiles)" Condition="@(OldCLZFiles) != ''">
|
||||||
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
|
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
|
||||||
</Delete>
|
</Delete>
|
||||||
<Message Text="Deleted files: '@(DeletedList)'" />
|
<Message Text="Deleted old CLZ files: '@(DeletedList)'" Condition="@(DeletedList) != ''" />
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="DeleteCPZ" BeforeTargets="PreBuildEvent" Condition="$(ProjectType) == 'Program' And $(TargetDir) != '' And Exists($(FileName))">
|
<Target Name="DeleteCPZ" BeforeTargets="CoreBuild" Condition="$(ProjectType) == 'Program' And $(TargetDir) != ''">
|
||||||
<Delete Files="$(TargetDir)$(TargetName).$(Version).$(TargetFramework).cpz">
|
<ItemGroup>
|
||||||
|
<OldCPZFiles Include="$(TargetDir)$(TargetName).*.$(TargetFramework).cpz" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Delete Files="@(OldCPZFiles)" Condition="@(OldCPZFiles) != ''">
|
||||||
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
|
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
|
||||||
</Delete>
|
</Delete>
|
||||||
<Message Text="Deleted files: '@(DeletedList)'" />
|
<Message Text="Deleted old CPZ files: '@(DeletedList)'" Condition="@(DeletedList) != ''" />
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="DeleteCPLZ" BeforeTargets="PreBuildEvent" Condition="$(ProjectType) == 'ProgramLibrary' And $(TargetDir) != '' And Exists($(FileName))">
|
<Target Name="DeleteCPLZ" BeforeTargets="CoreBuild" Condition="$(ProjectType) == 'ProgramLibrary' And $(TargetDir) != ''">
|
||||||
<Delete Files="$(TargetDir)$(TargetName).$(Version).$(TargetFramework).cplz">
|
<ItemGroup>
|
||||||
|
<OldCPLZFiles Include="$(TargetDir)$(TargetName).*.$(TargetFramework).cplz" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Delete Files="@(OldCPLZFiles)" Condition="@(OldCPLZFiles) != ''">
|
||||||
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
|
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
|
||||||
</Delete>
|
</Delete>
|
||||||
<Message Text="Deleted files: '@(DeletedList)'" />
|
<Message Text="Deleted old CPLZ files: '@(DeletedList)'" Condition="@(DeletedList) != ''" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="CreateCPLZ" AfterTargets="Build" Condition="$(ProjectType) == 'ProgramLibrary' And $(TargetDir) != ''" DependsOnTargets="DeleteCPLZ">
|
<Target Name="CreateCPLZ" AfterTargets="Build" Condition="$(ProjectType) == 'ProgramLibrary' And $(TargetDir) != ''" DependsOnTargets="DeleteCPLZ">
|
||||||
|
|||||||
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,11 +1,14 @@
|
|||||||
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 PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
namespace PepperDash.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the string event handler for line events on the gather
|
/// Defines the string event handler for line events on the gather
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
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;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
namespace PepperDash.Core
|
namespace PepperDash.Core
|
||||||
{
|
{
|
||||||
@@ -36,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
|
||||||
@@ -107,7 +107,7 @@ namespace PepperDash.Core
|
|||||||
TxStreamDebuggingIsEnabled = true;
|
TxStreamDebuggingIsEnabled = true;
|
||||||
|
|
||||||
Debug.SetDeviceDebugSettings(ParentDeviceKey, setting);
|
Debug.SetDeviceDebugSettings(ParentDeviceKey, setting);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -135,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,8 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
namespace PepperDash.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a ControlPropertiesConfig
|
/// Represents a ControlPropertiesConfig
|
||||||
|
|||||||
@@ -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,19 +78,19 @@ 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; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// S+ helper for IsConnected
|
/// S+ helper for IsConnected
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -99,15 +99,15 @@ 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
|
||||||
{
|
{
|
||||||
return _client == null ? SocketStatus.SOCKET_STATUS_NO_CONNECT : _client.ClientStatus;
|
return _client == null ? SocketStatus.SOCKET_STATUS_NO_CONNECT : _client.ClientStatus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,21 +124,21 @@ namespace PepperDash.Core
|
|||||||
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
||||||
CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
|
CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <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);
|
||||||
@@ -180,7 +180,7 @@ namespace PepperDash.Core
|
|||||||
/// <param name="programEventType"></param>
|
/// <param name="programEventType"></param>
|
||||||
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
|
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
|
||||||
{
|
{
|
||||||
if (programEventType != eProgramStatusEventType.Stopping)
|
if (programEventType != eProgramStatusEventType.Stopping)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Debug.Console(1, this, "Program stopping. Disabling Server");
|
Debug.Console(1, this, "Program stopping. Disabling Server");
|
||||||
@@ -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;
|
||||||
@@ -251,7 +265,7 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (numBytes <= 0)
|
if (numBytes <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var sourceIp = Server.IPAddressLastMessageReceivedFrom;
|
var sourceIp = Server.IPAddressLastMessageReceivedFrom;
|
||||||
@@ -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)}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
namespace PepperDash.Essentials.Core.Communications
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Crestron Control Methods for a comm object
|
/// Crestron Control Methods for a comm object
|
||||||
@@ -68,6 +74,14 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Secure TCP/IP
|
/// Secure TCP/IP
|
||||||
/// </summary>
|
/// </summary>
|
||||||
SecureTcpIp
|
SecureTcpIp,
|
||||||
|
/// <summary>
|
||||||
|
/// Used when comms needs to be handled in SIMPL and bridged opposite the normal direction
|
||||||
|
/// </summary>
|
||||||
|
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}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,23 +15,23 @@ namespace PepperDash.Core
|
|||||||
/// Unique Key
|
/// Unique Key
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Key { get; protected set; }
|
public string Key { get; protected set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Name
|
/// Gets or sets the Name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; protected set; }
|
public string Name { get; protected set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Gets or sets a value indicating whether the device is enabled
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enabled { get; protected set; }
|
public bool Enabled { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// A place to store reference to the original config object, if any. These values should
|
// /// A place to store reference to the original config object, if any. These values should
|
||||||
/// NOT be used as properties on the device as they are all publicly-settable values.
|
// /// NOT be used as properties on the device as they are all publicly-settable values.
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
//public DeviceConfig Config { get; private set; }
|
//public DeviceConfig Config { get; private set; }
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Helper method to check if Config exists
|
// /// Helper method to check if Config exists
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
//public bool HasConfig { get { return Config != null; } }
|
//public bool HasConfig { get { return Config != null; } }
|
||||||
|
|
||||||
List<Action> _PreActivationActions;
|
List<Action> _PreActivationActions;
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ namespace PepperDash.Core.JsonToSimpl
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static JObject ParseObject(string json)
|
public static JObject ParseObject(string json)
|
||||||
{
|
{
|
||||||
#if NET8_0
|
#if NET6_0
|
||||||
using (var reader = new JsonTextReader(new System.IO.StringReader(json)))
|
using (var reader = new JsonTextReader(new System.IO.StringReader(json)))
|
||||||
#else
|
#else
|
||||||
using (var reader = new JsonTextReader(new Crestron.SimplSharp.CrestronIO.StringReader(json)))
|
using (var reader = new JsonTextReader(new Crestron.SimplSharp.CrestronIO.StringReader(json)))
|
||||||
@@ -186,7 +186,7 @@ namespace PepperDash.Core.JsonToSimpl
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static JArray ParseArray(string json)
|
public static JArray ParseArray(string json)
|
||||||
{
|
{
|
||||||
#if NET8_0
|
#if NET6_0
|
||||||
using (var reader = new JsonTextReader(new System.IO.StringReader(json)))
|
using (var reader = new JsonTextReader(new System.IO.StringReader(json)))
|
||||||
#else
|
#else
|
||||||
using (var reader = new JsonTextReader(new Crestron.SimplSharp.CrestronIO.StringReader(json)))
|
using (var reader = new JsonTextReader(new Crestron.SimplSharp.CrestronIO.StringReader(json)))
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
using Crestron.SimplSharp;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
using Crestron.SimplSharp.CrestronDataStore;
|
using Crestron.SimplSharp.CrestronDataStore;
|
||||||
using Crestron.SimplSharp.CrestronIO;
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
using Crestron.SimplSharp.CrestronLogger;
|
using Crestron.SimplSharp.CrestronLogger;
|
||||||
@@ -11,15 +16,10 @@ using Serilog.Events;
|
|||||||
using Serilog.Formatting.Compact;
|
using Serilog.Formatting.Compact;
|
||||||
using Serilog.Formatting.Json;
|
using Serilog.Formatting.Json;
|
||||||
using Serilog.Templates;
|
using Serilog.Templates;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace PepperDash.Core
|
namespace PepperDash.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains debug commands for use in various situations
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Debug
|
public static class Debug
|
||||||
{
|
{
|
||||||
@@ -40,21 +40,27 @@ 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>
|
||||||
|
/// Gets the minimum log level for the websocket sink.
|
||||||
|
/// </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;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the websocket sink for debug logging.
|
||||||
|
/// </summary>
|
||||||
public static DebugWebsocketSink WebsocketSink
|
public static DebugWebsocketSink WebsocketSink
|
||||||
{
|
{
|
||||||
get { return _websocketSink; }
|
get { return _websocketSink; }
|
||||||
@@ -91,29 +97,33 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
private const int SaveTimeoutMs = 30000;
|
private const int SaveTimeoutMs = 30000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether the system is running on an appliance.
|
||||||
|
/// </summary>
|
||||||
public static bool IsRunningOnAppliance = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance;
|
public static bool IsRunningOnAppliance = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the PepperDashCoreVersion
|
/// Gets or sets the PepperDashCoreVersion
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string PepperDashCoreVersion { get; private set; }
|
public static string PepperDashCoreVersion { get; private set; }
|
||||||
|
|
||||||
private static CTimer _saveTimer;
|
private static CTimer _saveTimer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When true, the IncludedExcludedKeys dict will contain keys to include.
|
/// When true, the IncludedExcludedKeys dict will contain keys to include.
|
||||||
/// When false (default), IncludedExcludedKeys will contain keys to exclude.
|
/// When false (default), IncludedExcludedKeys will contain keys to exclude.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static bool _excludeAllMode;
|
private static bool _excludeAllMode;
|
||||||
|
|
||||||
//static bool ExcludeNoKeyMessages;
|
private static readonly Dictionary<string, object> IncludedExcludedKeys;
|
||||||
|
|
||||||
private static readonly Dictionary<string, object> IncludedExcludedKeys;
|
|
||||||
|
|
||||||
private static readonly LoggerConfiguration _defaultLoggerConfiguration;
|
private static readonly LoggerConfiguration _defaultLoggerConfiguration;
|
||||||
|
|
||||||
private static LoggerConfiguration _loggerConfiguration;
|
private static LoggerConfiguration _loggerConfiguration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the logger configuration for the debug logging.
|
||||||
|
/// </summary>
|
||||||
public static LoggerConfiguration LoggerConfiguration => _loggerConfiguration;
|
public static LoggerConfiguration LoggerConfiguration => _loggerConfiguration;
|
||||||
|
|
||||||
static Debug()
|
static Debug()
|
||||||
@@ -128,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));
|
||||||
|
|
||||||
@@ -144,7 +154,7 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
CrestronConsole.PrintLine($"Saving log files to {logFilePath}");
|
CrestronConsole.PrintLine($"Saving log files to {logFilePath}");
|
||||||
|
|
||||||
var errorLogTemplate = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance
|
var errorLogTemplate = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance
|
||||||
? "{@t:fff}ms [{@l:u4}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}"
|
? "{@t:fff}ms [{@l:u4}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}"
|
||||||
: "[{@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}";
|
: "[{@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}";
|
||||||
|
|
||||||
@@ -152,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
|
||||||
@@ -193,27 +203,27 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
CrestronConsole.PrintLine(msg);
|
CrestronConsole.PrintLine(msg);
|
||||||
|
|
||||||
LogMessage(LogEventLevel.Information,msg);
|
LogMessage(LogEventLevel.Information, msg);
|
||||||
|
|
||||||
|
IncludedExcludedKeys = new Dictionary<string, object>();
|
||||||
|
|
||||||
IncludedExcludedKeys = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (CrestronEnvironment.RuntimeEnvironment == eRuntimeEnvironment.SimplSharpPro)
|
if (CrestronEnvironment.RuntimeEnvironment == eRuntimeEnvironment.SimplSharpPro)
|
||||||
{
|
{
|
||||||
// Add command to console
|
// Add command to console
|
||||||
CrestronConsole.AddNewConsoleCommand(SetDoNotLoadOnNextBootFromConsole, "donotloadonnextboot",
|
CrestronConsole.AddNewConsoleCommand(SetDoNotLoadOnNextBootFromConsole, "donotloadonnextboot",
|
||||||
"donotloadonnextboot:P [true/false]: Should the application load on next boot", ConsoleAccessLevelEnum.AccessOperator);
|
"donotloadonnextboot:P [true/false]: Should the application load on next boot", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
CrestronConsole.AddNewConsoleCommand(SetDebugFromConsole, "appdebug",
|
CrestronConsole.AddNewConsoleCommand(SetDebugFromConsole, "appdebug",
|
||||||
"appdebug:P [0-5]: Sets the application's console debug message level",
|
"appdebug:P [0-5]: Sets the application's console debug message level",
|
||||||
ConsoleAccessLevelEnum.AccessOperator);
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(ShowDebugLog, "appdebuglog",
|
CrestronConsole.AddNewConsoleCommand(ShowDebugLog, "appdebuglog",
|
||||||
"appdebuglog:P [all] Use \"all\" for full log.",
|
"appdebuglog:P [all] Use \"all\" for full log.",
|
||||||
ConsoleAccessLevelEnum.AccessOperator);
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(s => CrestronLogger.Clear(false), "appdebugclear",
|
CrestronConsole.AddNewConsoleCommand(s => CrestronLogger.Clear(false), "appdebugclear",
|
||||||
"appdebugclear:P Clears the current custom log",
|
"appdebugclear:P Clears the current custom log",
|
||||||
ConsoleAccessLevelEnum.AccessOperator);
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(SetDebugFilterFromConsole, "appdebugfilter",
|
CrestronConsole.AddNewConsoleCommand(SetDebugFilterFromConsole, "appdebugfilter",
|
||||||
"appdebugfilter [params]", ConsoleAccessLevelEnum.AccessOperator);
|
"appdebugfilter [params]", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
|
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
|
||||||
@@ -224,13 +234,16 @@ namespace PepperDash.Core
|
|||||||
Level = context.Level;
|
Level = context.Level;
|
||||||
DoNotLoadConfigOnNextBoot = context.DoNotLoadOnNextBoot;
|
DoNotLoadConfigOnNextBoot = context.DoNotLoadOnNextBoot;
|
||||||
|
|
||||||
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>
|
||||||
@@ -257,22 +270,28 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = CrestronDataStoreStatic.GetLocalIntValue(levelStoreKey, out int logLevel);
|
var result = CrestronDataStoreStatic.GetLocalIntValue(levelStoreKey, out int logLevel);
|
||||||
|
|
||||||
if (result != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
if (result != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||||
{
|
{
|
||||||
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");
|
||||||
return LogEventLevel.Information;
|
|
||||||
|
CrestronDataStoreStatic.SetLocalIntValue(levelStoreKey, levelStoreKey == ErrorLogLevelStoreKey ? (int)LogEventLevel.Warning : (int)LogEventLevel.Information);
|
||||||
|
|
||||||
|
return levelStoreKey == ErrorLogLevelStoreKey ? LogEventLevel.Warning : LogEventLevel.Information;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(logLevel < 0 || logLevel > 5)
|
if (logLevel < 0 || logLevel > 5)
|
||||||
{
|
{
|
||||||
CrestronConsole.PrintLine($"Stored Log level not valid for {levelStoreKey}: {logLevel}. Setting level to {LogEventLevel.Information}");
|
CrestronConsole.PrintLine($"Stored Log level not valid for {levelStoreKey}: {logLevel}. Setting level to {LogEventLevel.Information}");
|
||||||
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)
|
||||||
{
|
{
|
||||||
CrestronConsole.PrintLine($"Exception retrieving log level for {levelStoreKey}: {ex.Message}");
|
CrestronConsole.PrintLine($"Exception retrieving log level for {levelStoreKey}: {ex.Message}");
|
||||||
return LogEventLevel.Information;
|
return LogEventLevel.Information;
|
||||||
@@ -284,7 +303,7 @@ namespace PepperDash.Core
|
|||||||
var assembly = Assembly.GetExecutingAssembly();
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
var ver =
|
var ver =
|
||||||
assembly
|
assembly
|
||||||
.GetCustomAttributes(typeof (AssemblyInformationalVersionAttribute), false);
|
.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false);
|
||||||
|
|
||||||
if (ver != null && ver.Length > 0)
|
if (ver != null && ver.Length > 0)
|
||||||
{
|
{
|
||||||
@@ -335,44 +354,104 @@ 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:
|
"Used to set the minimum level of debug messages:\r\n" +
|
||||||
{_logLevels[0]} = 0
|
"Usage: appdebug:P [sink] [level]\r\n" +
|
||||||
{_logLevels[1]} = 1
|
" sink: console (default), errorlog, file, all\r\n" +
|
||||||
{_logLevels[2]} = 2
|
" all: sets all sinks to the specified level\r\n" +
|
||||||
{_logLevels[3]} = 3
|
" level: 0-5 or LogEventLevel name\r\n" +
|
||||||
{_logLevels[4]} = 4
|
$"{_logLevels[0]} = 0\r\n" +
|
||||||
{_logLevels[5]} = 5");
|
$"{_logLevels[1]} = 1\r\n" +
|
||||||
|
$"{_logLevels[2]} = 2\r\n" +
|
||||||
|
$"{_logLevels[3]} = 3\r\n" +
|
||||||
|
$"{_logLevels[4]} = 4\r\n" +
|
||||||
|
$"{_logLevels[5]} = 5");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
if(levelInt < 0 || levelInt > 5)
|
// Single token - assume it's a level for console sink
|
||||||
|
sinkName = "console";
|
||||||
|
levelToken = tokens[0];
|
||||||
|
}
|
||||||
|
else if (tokens.Length == 2)
|
||||||
|
{
|
||||||
|
// Two tokens - first is sink, second is level
|
||||||
|
sinkName = tokens[0].ToLowerInvariant();
|
||||||
|
levelToken = tokens[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [sink] [level]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the level using the same logic as before
|
||||||
|
LogEventLevel level;
|
||||||
|
|
||||||
|
if (int.TryParse(levelToken, out var levelInt))
|
||||||
|
{
|
||||||
|
if (levelInt < 0 || levelInt > 5)
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level. If using a number, value must be between 0-5");
|
CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelToken} to valid log level. If using a number, value must be between 0-5");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SetDebugLevel((uint) levelInt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Enum.TryParse<LogEventLevel>(levelString, 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]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,7 +464,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetDebugLevel(uint level)
|
public static void SetDebugLevel(uint level)
|
||||||
{
|
{
|
||||||
if(!_logLevels.TryGetValue(level, out var logLevel))
|
if (!_logLevels.TryGetValue(level, out var logLevel))
|
||||||
{
|
{
|
||||||
logLevel = LogEventLevel.Information;
|
logLevel = LogEventLevel.Information;
|
||||||
|
|
||||||
@@ -402,14 +481,14 @@ 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}");
|
||||||
|
|
||||||
var err = CrestronDataStoreStatic.SetLocalIntValue(LevelStoreKey, (int) level);
|
var err = CrestronDataStoreStatic.SetLocalIntValue(LevelStoreKey, (int)level);
|
||||||
|
|
||||||
CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}");
|
CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}");
|
||||||
|
|
||||||
@@ -422,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>
|
||||||
@@ -439,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>
|
||||||
@@ -452,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>
|
||||||
@@ -491,83 +580,83 @@ namespace PepperDash.Core
|
|||||||
/// Callback for console command
|
/// Callback for console command
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="items"></param>
|
/// <param name="items"></param>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SetDebugFilterFromConsole method
|
/// SetDebugFilterFromConsole method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetDebugFilterFromConsole(string items)
|
public static void SetDebugFilterFromConsole(string items)
|
||||||
{
|
{
|
||||||
var str = items.Trim();
|
var str = items.Trim();
|
||||||
if (str == "?")
|
if (str == "?")
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse("Usage:\r APPDEBUGFILTER key1 key2 key3....\r " +
|
CrestronConsole.ConsoleCommandResponse("Usage:\r APPDEBUGFILTER key1 key2 key3....\r " +
|
||||||
"+all: at beginning puts filter into 'default include' mode\r" +
|
"+all: at beginning puts filter into 'default include' mode\r" +
|
||||||
" All keys that follow will be excluded from output.\r" +
|
" All keys that follow will be excluded from output.\r" +
|
||||||
"-all: at beginning puts filter into 'default exclude all' mode.\r" +
|
"-all: at beginning puts filter into 'default exclude all' mode.\r" +
|
||||||
" All keys that follow will be the only keys that are shown\r" +
|
" All keys that follow will be the only keys that are shown\r" +
|
||||||
"+nokey: Enables messages with no key (default)\r" +
|
"+nokey: Enables messages with no key (default)\r" +
|
||||||
"-nokey: Disables messages with no key.\r" +
|
"-nokey: Disables messages with no key.\r" +
|
||||||
"(nokey settings are independent of all other settings)");
|
"(nokey settings are independent of all other settings)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var keys = Regex.Split(str, @"\s*");
|
var keys = Regex.Split(str, @"\s*");
|
||||||
foreach (var keyToken in keys)
|
foreach (var keyToken in keys)
|
||||||
{
|
{
|
||||||
var lkey = keyToken.ToLower();
|
var lkey = keyToken.ToLower();
|
||||||
if (lkey == "+all")
|
if (lkey == "+all")
|
||||||
{
|
{
|
||||||
IncludedExcludedKeys.Clear();
|
IncludedExcludedKeys.Clear();
|
||||||
_excludeAllMode = false;
|
_excludeAllMode = false;
|
||||||
}
|
}
|
||||||
else if (lkey == "-all")
|
else if (lkey == "-all")
|
||||||
{
|
{
|
||||||
IncludedExcludedKeys.Clear();
|
IncludedExcludedKeys.Clear();
|
||||||
_excludeAllMode = true;
|
_excludeAllMode = true;
|
||||||
}
|
}
|
||||||
//else if (lkey == "+nokey")
|
//else if (lkey == "+nokey")
|
||||||
//{
|
//{
|
||||||
// ExcludeNoKeyMessages = false;
|
// ExcludeNoKeyMessages = false;
|
||||||
//}
|
//}
|
||||||
//else if (lkey == "-nokey")
|
//else if (lkey == "-nokey")
|
||||||
//{
|
//{
|
||||||
// ExcludeNoKeyMessages = true;
|
// ExcludeNoKeyMessages = true;
|
||||||
//}
|
//}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string key;
|
string key;
|
||||||
if (lkey.StartsWith("-"))
|
if (lkey.StartsWith("-"))
|
||||||
{
|
{
|
||||||
key = lkey.Substring(1);
|
key = lkey.Substring(1);
|
||||||
// if in exclude all mode, we need to remove this from the inclusions
|
// if in exclude all mode, we need to remove this from the inclusions
|
||||||
if (_excludeAllMode)
|
if (_excludeAllMode)
|
||||||
{
|
{
|
||||||
if (IncludedExcludedKeys.ContainsKey(key))
|
if (IncludedExcludedKeys.ContainsKey(key))
|
||||||
IncludedExcludedKeys.Remove(key);
|
IncludedExcludedKeys.Remove(key);
|
||||||
}
|
}
|
||||||
// otherwise include all mode, add to the exclusions
|
// otherwise include all mode, add to the exclusions
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IncludedExcludedKeys[key] = new object();
|
IncludedExcludedKeys[key] = new object();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lkey.StartsWith("+"))
|
else if (lkey.StartsWith("+"))
|
||||||
{
|
{
|
||||||
key = lkey.Substring(1);
|
key = lkey.Substring(1);
|
||||||
// if in exclude all mode, we need to add this as inclusion
|
// if in exclude all mode, we need to add this as inclusion
|
||||||
if (_excludeAllMode)
|
if (_excludeAllMode)
|
||||||
{
|
{
|
||||||
|
|
||||||
IncludedExcludedKeys[key] = new object();
|
IncludedExcludedKeys[key] = new object();
|
||||||
}
|
}
|
||||||
// otherwise include all mode, remove this from exclusions
|
// otherwise include all mode, remove this from exclusions
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (IncludedExcludedKeys.ContainsKey(key))
|
if (IncludedExcludedKeys.ContainsKey(key))
|
||||||
IncludedExcludedKeys.Remove(key);
|
IncludedExcludedKeys.Remove(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -595,7 +684,7 @@ namespace PepperDash.Core
|
|||||||
public static object GetDeviceDebugSettingsForKey(string deviceKey)
|
public static object GetDeviceDebugSettingsForKey(string deviceKey)
|
||||||
{
|
{
|
||||||
return _contexts.GetDebugSettingsForKey(deviceKey);
|
return _contexts.GetDebugSettingsForKey(deviceKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the flag to prevent application starting on next boot
|
/// Sets the flag to prevent application starting on next boot
|
||||||
@@ -654,9 +743,15 @@ namespace PepperDash.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logs a message at the specified log level.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="level">Level to log at</param>
|
||||||
|
/// <param name="message">Message template</param>
|
||||||
|
/// <param name="args">Args to put into message template</param>
|
||||||
public static void LogMessage(LogEventLevel level, string message, params object[] args)
|
public static void LogMessage(LogEventLevel level, string message, params object[] args)
|
||||||
{
|
{
|
||||||
_logger.Write(level, message, args);
|
_logger.Write(level, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -692,7 +787,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogVerbose(IKeyed keyed, string message, params object[] args)
|
public static void LogVerbose(IKeyed keyed, string message, params object[] args)
|
||||||
{
|
{
|
||||||
using(LogContext.PushProperty("Key", keyed?.Key))
|
using (LogContext.PushProperty("Key", keyed?.Key))
|
||||||
{
|
{
|
||||||
_logger.Write(LogEventLevel.Verbose, message, args);
|
_logger.Write(LogEventLevel.Verbose, message, args);
|
||||||
}
|
}
|
||||||
@@ -703,7 +798,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogVerbose(Exception ex, IKeyed keyed, string message, params object[] args)
|
public static void LogVerbose(Exception ex, IKeyed keyed, string message, params object[] args)
|
||||||
{
|
{
|
||||||
using(LogContext.PushProperty("Key", keyed?.Key))
|
using (LogContext.PushProperty("Key", keyed?.Key))
|
||||||
{
|
{
|
||||||
_logger.Write(LogEventLevel.Verbose, ex, message, args);
|
_logger.Write(LogEventLevel.Verbose, ex, message, args);
|
||||||
}
|
}
|
||||||
@@ -722,7 +817,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogVerbose(Exception ex, string message, params object[] args)
|
public static void LogVerbose(Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
_logger.Write(LogEventLevel.Verbose, ex, null, message, args);
|
_logger.Write(LogEventLevel.Verbose, ex, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -798,7 +893,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogInformation(Exception ex, string message, params object[] args)
|
public static void LogInformation(Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
_logger.Write(LogEventLevel.Information, ex, null, message, args);
|
_logger.Write(LogEventLevel.Information, ex, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -836,7 +931,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogWarning(Exception ex, string message, params object[] args)
|
public static void LogWarning(Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
_logger.Write(LogEventLevel.Warning, ex, null, message, args);
|
_logger.Write(LogEventLevel.Warning, ex, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -874,7 +969,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogError(Exception ex, string message, params object[] args)
|
public static void LogError(Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
_logger.Write(LogEventLevel.Error, ex, null, message, args);
|
_logger.Write(LogEventLevel.Error, ex, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -912,7 +1007,7 @@ namespace PepperDash.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogFatal(Exception ex, string message, params object[] args)
|
public static void LogFatal(Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
_logger.Write(LogEventLevel.Fatal, ex, null, message, args);
|
_logger.Write(LogEventLevel.Fatal, ex, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -923,7 +1018,7 @@ namespace PepperDash.Core
|
|||||||
if (!_logLevels.ContainsKey(level)) return;
|
if (!_logLevels.ContainsKey(level)) return;
|
||||||
|
|
||||||
var logLevel = _logLevels[level];
|
var logLevel = _logLevels[level];
|
||||||
|
|
||||||
LogMessage(logLevel, format, items);
|
LogMessage(logLevel, format, items);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -978,7 +1073,7 @@ namespace PepperDash.Core
|
|||||||
[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")]
|
||||||
public static void Console(uint level, IKeyed dev, ErrorLogLevel errorLogLevel,
|
public static void Console(uint level, IKeyed dev, ErrorLogLevel errorLogLevel,
|
||||||
string format, params object[] items)
|
string format, params object[] items)
|
||||||
{
|
{
|
||||||
LogMessage(level, dev, format, items);
|
LogMessage(level, dev, format, items);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -986,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)
|
||||||
{
|
{
|
||||||
@@ -1001,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);
|
||||||
@@ -1122,7 +1211,7 @@ namespace PepperDash.Core
|
|||||||
return string.Format(@"\user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber);
|
return string.Format(@"\user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Format("{0}{1}user{1}debugSettings{1}{2}.json",Directory.GetApplicationRootDirectory(), Path.DirectorySeparatorChar, InitialParametersClass.RoomId);
|
return string.Format("{0}{1}user{1}debugSettings{1}{2}.json", Directory.GetApplicationRootDirectory(), Path.DirectorySeparatorChar, InitialParametersClass.RoomId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1133,15 +1222,15 @@ namespace PepperDash.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Error
|
/// Error
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Error,
|
Error,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Warning
|
/// Warning
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Warning,
|
Warning,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Notice
|
/// Notice
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Notice,
|
Notice,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// None
|
/// None
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ namespace PepperDash.Core
|
|||||||
CrestronConsole.PrintLine(message);
|
CrestronConsole.PrintLine(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for DebugConsoleSink
|
||||||
|
/// </summary>
|
||||||
public DebugConsoleSink(ITextFormatter formatProvider )
|
public DebugConsoleSink(ITextFormatter formatProvider )
|
||||||
{
|
{
|
||||||
_textFormatter = formatProvider ?? new JsonFormatter();
|
_textFormatter = formatProvider ?? new JsonFormatter();
|
||||||
@@ -48,6 +51,9 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for DebugConsoleSink
|
||||||
|
/// </summary>
|
||||||
public static class DebugConsoleSinkExtensions
|
public static class DebugConsoleSinkExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ namespace PepperDash.Core.Logging
|
|||||||
CrestronLogger.WriteToLog(message, (uint)logEvent.Level);
|
CrestronLogger.WriteToLog(message, (uint)logEvent.Level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for DebugCrestronLoggerSink
|
||||||
|
/// </summary>
|
||||||
public DebugCrestronLoggerSink()
|
public DebugCrestronLoggerSink()
|
||||||
{
|
{
|
||||||
CrestronLogger.Initialize(1, LoggerModeEnum.RM);
|
CrestronLogger.Initialize(1, LoggerModeEnum.RM);
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ namespace PepperDash.Core.Logging
|
|||||||
handler(message);
|
handler(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for DebugErrorLogSink
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="formatter">text formatter for log output</param>
|
||||||
public DebugErrorLogSink(ITextFormatter formatter = null)
|
public DebugErrorLogSink(ITextFormatter formatter = null)
|
||||||
{
|
{
|
||||||
_formatter = formatter;
|
_formatter = formatter;
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
using Serilog.Events;
|
using System;
|
||||||
using System;
|
using Serilog.Events;
|
||||||
using Log = PepperDash.Core.Debug;
|
using Log = PepperDash.Core.Debug;
|
||||||
|
|
||||||
namespace PepperDash.Core.Logging
|
namespace PepperDash.Core.Logging
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for logging on IKeyed objects
|
||||||
|
/// </summary>
|
||||||
public static class DebugExtensions
|
public static class DebugExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -11,7 +14,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogException(this IKeyed device, Exception ex, string message, params object[] args)
|
public static void LogException(this IKeyed device, Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(ex, message, device, args);
|
Log.LogMessage(ex, message, device: device, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -19,7 +22,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogVerbose(this IKeyed device, Exception ex, string message, params object[] args)
|
public static void LogVerbose(this IKeyed device, Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Verbose, ex, message, device, args);
|
Log.LogVerbose(ex, device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -27,7 +30,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogVerbose(this IKeyed device, string message, params object[] args)
|
public static void LogVerbose(this IKeyed device, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Verbose, device, message, args);
|
Log.LogVerbose(device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -35,7 +38,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogDebug(this IKeyed device, Exception ex, string message, params object[] args)
|
public static void LogDebug(this IKeyed device, Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Debug, ex, message, device, args);
|
Log.LogDebug(ex, device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -43,7 +46,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogDebug(this IKeyed device, string message, params object[] args)
|
public static void LogDebug(this IKeyed device, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Debug, device, message, args);
|
Log.LogDebug(device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -51,7 +54,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogInformation(this IKeyed device, Exception ex, string message, params object[] args)
|
public static void LogInformation(this IKeyed device, Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Information, ex, message, device, args);
|
Log.LogInformation(ex, device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -59,7 +62,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogInformation(this IKeyed device, string message, params object[] args)
|
public static void LogInformation(this IKeyed device, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Information, device, message, args);
|
Log.LogInformation(device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -67,7 +70,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogWarning(this IKeyed device, Exception ex, string message, params object[] args)
|
public static void LogWarning(this IKeyed device, Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Warning, ex, message, device, args);
|
Log.LogWarning(ex, device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -75,7 +78,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogWarning(this IKeyed device, string message, params object[] args)
|
public static void LogWarning(this IKeyed device, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Warning, device, message, args);
|
Log.LogWarning(device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -83,7 +86,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogError(this IKeyed device, Exception ex, string message, params object[] args)
|
public static void LogError(this IKeyed device, Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Error, ex, message, device, args);
|
Log.LogError(ex, device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -91,7 +94,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogError(this IKeyed device, string message, params object[] args)
|
public static void LogError(this IKeyed device, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Error, device, message, args);
|
Log.LogError(device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -99,7 +102,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogFatal(this IKeyed device, Exception ex, string message, params object[] args)
|
public static void LogFatal(this IKeyed device, Exception ex, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Fatal, ex, message, device, args);
|
Log.LogFatal(ex, device, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -107,7 +110,7 @@ namespace PepperDash.Core.Logging
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogFatal(this IKeyed device, string message, params object[] args)
|
public static void LogFatal(this IKeyed device, string message, params object[] args)
|
||||||
{
|
{
|
||||||
Log.LogMessage(LogEventLevel.Fatal, device, message, args);
|
Log.LogFatal(device, message, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ namespace PepperDash.Core
|
|||||||
private const string _certificateName = "selfCres";
|
private const string _certificateName = "selfCres";
|
||||||
private const string _certificatePassword = "cres12345";
|
private const string _certificatePassword = "cres12345";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Port
|
||||||
|
/// </summary>
|
||||||
public int Port
|
public int Port
|
||||||
{ get
|
{ get
|
||||||
{
|
{
|
||||||
@@ -41,6 +44,9 @@ namespace PepperDash.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Url
|
||||||
|
/// </summary>
|
||||||
public string Url
|
public string Url
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -58,6 +64,11 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
private readonly ITextFormatter _textFormatter;
|
private readonly ITextFormatter _textFormatter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for DebugWebsocketSink
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="formatProvider">text formatter for log output</param>
|
||||||
|
|
||||||
public DebugWebsocketSink(ITextFormatter formatProvider)
|
public DebugWebsocketSink(ITextFormatter formatProvider)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -217,6 +228,9 @@ namespace PepperDash.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for DebugWebsocketSink
|
||||||
|
/// </summary>
|
||||||
public static class DebugWebsocketSinkExtensions
|
public static class DebugWebsocketSinkExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -237,6 +251,9 @@ namespace PepperDash.Core
|
|||||||
{
|
{
|
||||||
private DateTime _connectionTime;
|
private DateTime _connectionTime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ConnectedDuration
|
||||||
|
/// </summary>
|
||||||
public TimeSpan ConnectedDuration
|
public TimeSpan ConnectedDuration
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -252,11 +269,17 @@ namespace PepperDash.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for DebugClient
|
||||||
|
/// </summary>
|
||||||
public DebugClient()
|
public DebugClient()
|
||||||
{
|
{
|
||||||
Debug.Console(0, "DebugClient Created");
|
Debug.Console(0, "DebugClient Created");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OnOpen method
|
||||||
|
/// </summary>
|
||||||
protected override void OnOpen()
|
protected override void OnOpen()
|
||||||
{
|
{
|
||||||
base.OnOpen();
|
base.OnOpen();
|
||||||
@@ -267,6 +290,9 @@ namespace PepperDash.Core
|
|||||||
_connectionTime = DateTime.Now;
|
_connectionTime = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OnMessage method
|
||||||
|
/// </summary>
|
||||||
protected override void OnMessage(MessageEventArgs e)
|
protected override void OnMessage(MessageEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnMessage(e);
|
base.OnMessage(e);
|
||||||
@@ -274,6 +300,9 @@ namespace PepperDash.Core
|
|||||||
Debug.Console(0, "WebSocket UiClient Message: {0}", e.Data);
|
Debug.Console(0, "WebSocket UiClient Message: {0}", e.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OnClose method
|
||||||
|
/// </summary>
|
||||||
protected override void OnClose(CloseEventArgs e)
|
protected override void OnClose(CloseEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnClose(e);
|
base.OnClose(e);
|
||||||
@@ -282,6 +311,9 @@ namespace PepperDash.Core
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OnError method
|
||||||
|
/// </summary>
|
||||||
protected override void OnError(WebSocketSharp.ErrorEventArgs e)
|
protected override void OnError(WebSocketSharp.ErrorEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnError(e);
|
base.OnError(e);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<RootNamespace>PepperDash.Core</RootNamespace>
|
<RootNamespace>PepperDash.Core</RootNamespace>
|
||||||
<AssemblyName>PepperDashCore</AssemblyName>
|
<AssemblyName>PepperDashCore</AssemblyName>
|
||||||
<TargetFramework>net8</TargetFramework>
|
<TargetFramework>net472</TargetFramework>
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
<NeutralLanguage>en</NeutralLanguage>
|
<NeutralLanguage>en</NeutralLanguage>
|
||||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
@@ -44,7 +44,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
|
<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
|
||||||
<PackageReference Include="Crestron.SimplSharp.SDK.Library" Version="2.21.90" />
|
<PackageReference Include="Crestron.SimplSharp.SDK.Library" Version="2.21.90" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
|
||||||
<PackageReference Include="Serilog" Version="3.1.1" />
|
<PackageReference Include="Serilog" Version="3.1.1" />
|
||||||
<PackageReference Include="Serilog.Expressions" Version="4.0.0" />
|
<PackageReference Include="Serilog.Expressions" Version="4.0.0" />
|
||||||
<PackageReference Include="Serilog.Formatting.Compact" Version="2.0.0" />
|
<PackageReference Include="Serilog.Formatting.Compact" Version="2.0.0" />
|
||||||
@@ -53,6 +52,9 @@
|
|||||||
<PackageReference Include="SSH.NET" Version="2024.2.0" />
|
<PackageReference Include="SSH.NET" Version="2024.2.0" />
|
||||||
<PackageReference Include="WebSocketSharp" Version="1.0.3-rc11" />
|
<PackageReference Include="WebSocketSharp" Version="1.0.3-rc11" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net6'">
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Comm\._GenericSshClient.cs" />
|
<Compile Remove="Comm\._GenericSshClient.cs" />
|
||||||
<Compile Remove="Comm\._GenericTcpIpClient.cs" />
|
<Compile Remove="Comm\._GenericTcpIpClient.cs" />
|
||||||
|
|||||||
@@ -5,9 +5,16 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace PepperDash.Core.Web.RequestHandlers
|
namespace PepperDash.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// CWS Base Async Handler, implements IHttpCwsHandler
|
||||||
|
/// </summary>
|
||||||
public abstract class WebApiBaseRequestAsyncHandler:IHttpCwsHandler
|
public abstract class WebApiBaseRequestAsyncHandler:IHttpCwsHandler
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, Func<HttpCwsContext, Task>> _handlers;
|
private readonly Dictionary<string, Func<HttpCwsContext, Task>> _handlers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether CORS is enabled
|
||||||
|
/// </summary>
|
||||||
protected readonly bool EnableCors;
|
protected readonly bool EnableCors;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ namespace PepperDash.Core.Web.RequestHandlers
|
|||||||
public abstract class WebApiBaseRequestHandler : IHttpCwsHandler
|
public abstract class WebApiBaseRequestHandler : IHttpCwsHandler
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, Action<HttpCwsContext>> _handlers;
|
private readonly Dictionary<string, Action<HttpCwsContext>> _handlers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether CORS is enabled
|
||||||
|
/// </summary>
|
||||||
protected readonly bool EnableCors;
|
protected readonly bool EnableCors;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ namespace PepperDash.Core.Web
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsRegistered { get; private set; }
|
public bool IsRegistered { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Http request handler
|
// /// Http request handler
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
//public IHttpCwsHandler HttpRequestHandler
|
//public IHttpCwsHandler HttpRequestHandler
|
||||||
//{
|
//{
|
||||||
// get { return _server.HttpRequestHandler; }
|
// get { return _server.HttpRequestHandler; }
|
||||||
@@ -58,9 +58,9 @@ namespace PepperDash.Core.Web
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Received request event handler
|
// /// Received request event handler
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
//public event EventHandler<HttpCwsRequestEventArgs> ReceivedRequestEvent
|
//public event EventHandler<HttpCwsRequestEventArgs> ReceivedRequestEvent
|
||||||
//{
|
//{
|
||||||
// add { _server.ReceivedRequestEvent += new HttpCwsRequestEventHandler(value); }
|
// add { _server.ReceivedRequestEvent += new HttpCwsRequestEventHandler(value); }
|
||||||
|
|||||||
@@ -6,24 +6,25 @@ using Crestron.SimplSharp;
|
|||||||
using Crestron.SimplSharpPro;
|
using Crestron.SimplSharpPro;
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
using Crestron.SimplSharpPro.EthernetCommunication;
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Essentials.Core.Communications;
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Core.Logging;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.Devices;
|
|
||||||
using PepperDash.Essentials.Core.JoinMaps;
|
|
||||||
using PepperDash.Essentials.Core.Monitoring;
|
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
//using PepperDash.Essentials.Devices.Common.Cameras;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base class for bridge API variants
|
/// Base class for bridge API variants
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete("Will be removed in v3.0.0")]
|
||||||
public abstract class BridgeApi : EssentialsDevice
|
public abstract class BridgeApi : EssentialsDevice
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">Device key</param>
|
||||||
protected BridgeApi(string key) :
|
protected BridgeApi(string key) :
|
||||||
base(key)
|
base(key)
|
||||||
{
|
{
|
||||||
@@ -32,23 +33,36 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a EiscApiAdvanced
|
/// Class to link devices and rooms to an EISC Instance
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EiscApiAdvanced : BridgeApi, ICommunicationMonitor
|
public class EiscApiAdvanced : BridgeApi, ICommunicationMonitor
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the PropertiesConfig
|
||||||
|
/// </summary>
|
||||||
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
|
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the JoinMaps dictionary
|
||||||
|
/// </summary>
|
||||||
public Dictionary<string, JoinMapBaseAdvanced> JoinMaps { get; private set; }
|
public Dictionary<string, JoinMapBaseAdvanced> JoinMaps { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the EISC instance
|
||||||
|
/// </summary>
|
||||||
public BasicTriList Eisc { get; private set; }
|
public BasicTriList Eisc { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dc">Device configuration</param>
|
||||||
|
/// <param name="eisc">EISC instance</param>
|
||||||
public EiscApiAdvanced(DeviceConfig dc, BasicTriList eisc) :
|
public EiscApiAdvanced(DeviceConfig dc, BasicTriList eisc) :
|
||||||
base(dc.Key)
|
base(dc.Key)
|
||||||
{
|
{
|
||||||
JoinMaps = new Dictionary<string, JoinMapBaseAdvanced>();
|
JoinMaps = new Dictionary<string, JoinMapBaseAdvanced>();
|
||||||
|
|
||||||
PropertiesConfig = dc.Properties.ToObject<EiscApiPropertiesConfig>();
|
PropertiesConfig = dc.Properties.ToObject<EiscApiPropertiesConfig>();
|
||||||
//PropertiesConfig = JsonConvert.DeserializeObject<EiscApiPropertiesConfig>(dc.Properties.ToString());
|
|
||||||
|
|
||||||
Eisc = eisc;
|
Eisc = eisc;
|
||||||
|
|
||||||
@@ -63,8 +77,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CustomActivate method
|
/// CustomActivate method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
|
||||||
public override bool CustomActivate()
|
public override bool CustomActivate()
|
||||||
{
|
{
|
||||||
CommunicationMonitor.Start();
|
CommunicationMonitor.Start();
|
||||||
@@ -86,7 +99,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
|
|
||||||
if (PropertiesConfig.Devices == null)
|
if (PropertiesConfig.Devices == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "No devices linked to this bridge");
|
this.LogDebug("No devices linked to this bridge");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,9 +120,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this,
|
this.LogWarning("{deviceKey} is not compatible with this bridge type. Please update the device.", device.Key);
|
||||||
"{0} is not compatible with this bridge type. Please use 'eiscapi' instead, or updae the device.",
|
|
||||||
device.Key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,34 +135,31 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
|
|
||||||
if (registerResult != eDeviceRegistrationUnRegistrationResponse.Success)
|
if (registerResult != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Registration result: {0}", registerResult);
|
this.LogVerbose("Registration result: {registerResult}", registerResult);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "EISC registration successful");
|
this.LogDebug("EISC registration successful");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// LinkRooms method
|
/// Link rooms to this EISC. Rooms MUST implement IBridgeAdvanced
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void LinkRooms()
|
public void LinkRooms()
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "Linking Rooms...");
|
this.LogDebug("Linking Rooms...");
|
||||||
|
|
||||||
if (PropertiesConfig.Rooms == null)
|
if (PropertiesConfig.Rooms == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "No rooms linked to this bridge.");
|
this.LogDebug("No rooms linked to this bridge.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var room in PropertiesConfig.Rooms)
|
foreach (var room in PropertiesConfig.Rooms)
|
||||||
{
|
{
|
||||||
var rm = DeviceManager.GetDeviceForKey(room.RoomKey) as IBridgeAdvanced;
|
if (!(DeviceManager.GetDeviceForKey(room.RoomKey) is IBridgeAdvanced rm))
|
||||||
|
|
||||||
if (rm == null)
|
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this,
|
this.LogDebug("Room {roomKey} does not implement IBridgeAdvanced. Skipping...", room.RoomKey);
|
||||||
"Room {0} does not implement IBridgeAdvanced. Skipping...", room.RoomKey);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,11 +170,8 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a join map
|
/// Adds a join map
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="deviceKey"></param>
|
/// <param name="deviceKey">The key of the device to add the join map for</param>
|
||||||
/// <param name="joinMap"></param>
|
/// <param name="joinMap">The join map to add</param>
|
||||||
/// <summary>
|
|
||||||
/// AddJoinMap method
|
|
||||||
/// </summary>
|
|
||||||
public void AddJoinMap(string deviceKey, JoinMapBaseAdvanced joinMap)
|
public void AddJoinMap(string deviceKey, JoinMapBaseAdvanced joinMap)
|
||||||
{
|
{
|
||||||
if (!JoinMaps.ContainsKey(deviceKey))
|
if (!JoinMaps.ContainsKey(deviceKey))
|
||||||
@@ -175,14 +180,13 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Unable to add join map with key '{0}'. Key already exists in JoinMaps dictionary", deviceKey);
|
this.LogWarning("Unable to add join map with key '{deviceKey}'. Key already exists in JoinMaps dictionary", deviceKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PrintJoinMaps method
|
/// PrintJoinMaps method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual void PrintJoinMaps()
|
public virtual void PrintJoinMaps()
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse("Join Maps for EISC IPID: {0}\r\n", Eisc.ID.ToString("X"));
|
CrestronConsole.ConsoleCommandResponse("Join Maps for EISC IPID: {0}\r\n", Eisc.ID.ToString("X"));
|
||||||
@@ -193,17 +197,17 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
joinMap.Value.PrintJoinMapInfo();
|
joinMap.Value.PrintJoinMapInfo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MarkdownForBridge method
|
/// MarkdownForBridge method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual void MarkdownForBridge(string bridgeKey)
|
public virtual void MarkdownForBridge(string bridgeKey)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Writing Joinmaps to files for EISC IPID: {0}", Eisc.ID.ToString("X"));
|
this.LogInformation("Writing Joinmaps to files for EISC IPID: {eiscId}", Eisc.ID.ToString("X"));
|
||||||
|
|
||||||
foreach (var joinMap in JoinMaps)
|
foreach (var joinMap in JoinMaps)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Generating markdown for device '{0}':", joinMap.Key);
|
this.LogInformation("Generating markdown for device '{deviceKey}':", joinMap.Key);
|
||||||
joinMap.Value.MarkdownJoinMapInfo(joinMap.Key, bridgeKey);
|
joinMap.Value.MarkdownJoinMapInfo(joinMap.Key, bridgeKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,53 +215,45 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prints the join map for a device by key
|
/// Prints the join map for a device by key
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="deviceKey"></param>
|
/// <param name="deviceKey">The key of the device to print the join map for</param>
|
||||||
/// <summary>
|
|
||||||
/// PrintJoinMapForDevice method
|
|
||||||
/// </summary>
|
|
||||||
public void PrintJoinMapForDevice(string deviceKey)
|
public void PrintJoinMapForDevice(string deviceKey)
|
||||||
{
|
{
|
||||||
var joinMap = JoinMaps[deviceKey];
|
var joinMap = JoinMaps[deviceKey];
|
||||||
|
|
||||||
if (joinMap == null)
|
if (joinMap == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Unable to find joinMap for device with key: '{0}'", deviceKey);
|
this.LogInformation("Unable to find joinMap for device with key: '{deviceKey}'", deviceKey);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
|
this.LogInformation("Join map for device '{deviceKey}' on EISC '{eiscKey}':", deviceKey, Key);
|
||||||
joinMap.PrintJoinMapInfo();
|
joinMap.PrintJoinMapInfo();
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prints the join map for a device by key
|
/// Prints the join map for a device by key in Markdown format
|
||||||
/// </summary>
|
|
||||||
/// <param name="deviceKey"></param>
|
|
||||||
/// <summary>
|
|
||||||
/// MarkdownJoinMapForDevice method
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="deviceKey">The key of the device to print the join map for</param>
|
||||||
|
/// <param name="bridgeKey">The key of the bridge to use for the Markdown output</param>
|
||||||
public void MarkdownJoinMapForDevice(string deviceKey, string bridgeKey)
|
public void MarkdownJoinMapForDevice(string deviceKey, string bridgeKey)
|
||||||
{
|
{
|
||||||
var joinMap = JoinMaps[deviceKey];
|
var joinMap = JoinMaps[deviceKey];
|
||||||
|
|
||||||
if (joinMap == null)
|
if (joinMap == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Unable to find joinMap for device with key: '{0}'", deviceKey);
|
this.LogInformation("Unable to find joinMap for device with key: '{deviceKey}'", deviceKey);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
|
this.LogInformation("Join map for device '{deviceKey}' on EISC '{eiscKey}':", deviceKey, Key);
|
||||||
joinMap.MarkdownJoinMapInfo(deviceKey, bridgeKey);
|
joinMap.MarkdownJoinMapInfo(deviceKey, bridgeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used for debugging to trigger an action based on a join number and type
|
/// Used for debugging to trigger an action based on a join number and type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="join"></param>
|
/// <param name="join">The join number to execute the action for</param>
|
||||||
/// <param name="type"></param>
|
/// <param name="type">The type of join (digital, analog, serial)</param>
|
||||||
/// <param name="state"></param>
|
/// <param name="state">The state to pass to the action</param>
|
||||||
/// <summary>
|
|
||||||
/// ExecuteJoinAction method
|
|
||||||
/// </summary>
|
|
||||||
public void ExecuteJoinAction(uint join, string type, object state)
|
public void ExecuteJoinAction(uint join, string type, object state)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -266,78 +262,87 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
{
|
{
|
||||||
case "digital":
|
case "digital":
|
||||||
{
|
{
|
||||||
var uo = Eisc.BooleanOutput[join].UserObject as Action<bool>;
|
if (Eisc.BooleanOutput[join].UserObject is Action<bool> userObject)
|
||||||
if (uo != null)
|
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Executing Action: {0}", uo.ToString());
|
this.LogVerbose("Executing Boolean Action");
|
||||||
uo(Convert.ToBoolean(state));
|
userObject(Convert.ToBoolean(state));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "User Action is null. Nothing to Execute");
|
this.LogVerbose("User Object is null. Nothing to Execute");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "analog":
|
case "analog":
|
||||||
{
|
{
|
||||||
var uo = Eisc.BooleanOutput[join].UserObject as Action<ushort>;
|
if (Eisc.UShortOutput[join].UserObject is Action<ushort> userObject)
|
||||||
if (uo != null)
|
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Executing Action: {0}", uo.ToString());
|
this.LogVerbose("Executing Analog Action");
|
||||||
uo(Convert.ToUInt16(state));
|
userObject(Convert.ToUInt16(state));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "User Action is null. Nothing to Execute"); break;
|
this.LogVerbose("User Object is null. Nothing to Execute");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case "serial":
|
case "serial":
|
||||||
{
|
{
|
||||||
var uo = Eisc.BooleanOutput[join].UserObject as Action<string>;
|
if (Eisc.StringOutput[join].UserObject is Action<string> userObject)
|
||||||
if (uo != null)
|
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Executing Action: {0}", uo.ToString());
|
this.LogVerbose("Executing Serial Action");
|
||||||
uo(Convert.ToString(state));
|
userObject(Convert.ToString(state));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "User Action is null. Nothing to Execute");
|
this.LogVerbose("User Object is null. Nothing to Execute");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Unknown join type. Use digital/serial/analog");
|
this.LogVerbose("Unknown join type. Use digital/serial/analog");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
|
this.LogError("ExecuteJoinAction error: {message}", e.Message);
|
||||||
|
this.LogDebug(e, "Stack Trace: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles incoming sig changes
|
/// Handle incoming sig changes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="currentDevice"></param>
|
/// <param name="currentDevice">BasicTriList device that triggered the event</param>
|
||||||
/// <param name="args"></param>
|
/// <param name="args">Event arguments containing the signal information</param>
|
||||||
protected void Eisc_SigChange(object currentDevice, SigEventArgs args)
|
protected void Eisc_SigChange(object currentDevice, SigEventArgs args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "EiscApiAdvanced change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
this.LogVerbose("EiscApiAdvanced change: {type} {number}={value}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||||
var uo = args.Sig.UserObject;
|
var userObject = args.Sig.UserObject;
|
||||||
|
|
||||||
if (uo == null) return;
|
if (userObject == null) return;
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "Executing Action: {0}", uo.ToString());
|
|
||||||
if (uo is Action<bool>)
|
if (userObject is Action<bool>)
|
||||||
(uo as Action<bool>)(args.Sig.BoolValue);
|
{
|
||||||
else if (uo is Action<ushort>)
|
this.LogDebug("Executing Boolean Action");
|
||||||
(uo as Action<ushort>)(args.Sig.UShortValue);
|
(userObject as Action<bool>)(args.Sig.BoolValue);
|
||||||
else if (uo is Action<string>)
|
}
|
||||||
(uo as Action<string>)(args.Sig.StringValue);
|
else if (userObject is Action<ushort>)
|
||||||
|
{
|
||||||
|
this.LogDebug("Executing Analog Action");
|
||||||
|
(userObject as Action<ushort>)(args.Sig.UShortValue);
|
||||||
|
}
|
||||||
|
else if (userObject is Action<string>)
|
||||||
|
{
|
||||||
|
this.LogDebug("Executing Serial Action");
|
||||||
|
(userObject as Action<string>)(args.Sig.StringValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Error in Eisc_SigChange handler: {0}", e);
|
this.LogError("Eisc_SigChange handler error: {message}", e.Message);
|
||||||
|
this.LogDebug(e, "Stack Trace: ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,22 +361,22 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class EiscApiPropertiesConfig
|
public class EiscApiPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("control")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Control
|
/// Gets or sets the Control
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("control")]
|
||||||
public EssentialsControlPropertiesConfig Control { get; set; }
|
public EssentialsControlPropertiesConfig Control { get; set; }
|
||||||
|
|
||||||
[JsonProperty("devices")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Devices
|
/// Gets or sets the Devices
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("devices")]
|
||||||
public List<ApiDevicePropertiesConfig> Devices { get; set; }
|
public List<ApiDevicePropertiesConfig> Devices { get; set; }
|
||||||
|
|
||||||
[JsonProperty("rooms")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Rooms
|
/// Gets or sets the Rooms
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("rooms")]
|
||||||
public List<ApiRoomPropertiesConfig> Rooms { get; set; }
|
public List<ApiRoomPropertiesConfig> Rooms { get; set; }
|
||||||
|
|
||||||
|
|
||||||
@@ -380,22 +385,22 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ApiDevicePropertiesConfig
|
public class ApiDevicePropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("deviceKey")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the DeviceKey
|
/// Gets or sets the DeviceKey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("deviceKey")]
|
||||||
public string DeviceKey { get; set; }
|
public string DeviceKey { get; set; }
|
||||||
|
|
||||||
[JsonProperty("joinStart")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the JoinStart
|
/// Gets or sets the JoinStart
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("joinStart")]
|
||||||
public uint JoinStart { get; set; }
|
public uint JoinStart { get; set; }
|
||||||
|
|
||||||
[JsonProperty("joinMapKey")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the JoinMapKey
|
/// Gets or sets the JoinMapKey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("joinMapKey")]
|
||||||
public string JoinMapKey { get; set; }
|
public string JoinMapKey { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,44 +409,55 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ApiRoomPropertiesConfig
|
public class ApiRoomPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("roomKey")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the RoomKey
|
/// Gets or sets the RoomKey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("roomKey")]
|
||||||
public string RoomKey { get; set; }
|
public string RoomKey { get; set; }
|
||||||
|
|
||||||
[JsonProperty("joinStart")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the JoinStart
|
/// Gets or sets the JoinStart
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("joinStart")]
|
||||||
public uint JoinStart { get; set; }
|
public uint JoinStart { get; set; }
|
||||||
|
|
||||||
[JsonProperty("joinMapKey")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the JoinMapKey
|
/// Gets or sets the JoinMapKey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("joinMapKey")]
|
||||||
public string JoinMapKey { get; set; }
|
public string JoinMapKey { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a EiscApiAdvancedFactory
|
/// Factory class for EiscApiAdvanced devices
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Supported types:
|
||||||
|
/// eiscapiadv - Create a standard EISC client over TCP/IP
|
||||||
|
/// eiscapiadvanced - Create a standard EISC client over TCP/IP
|
||||||
|
/// eiscapiadvancedserver - Create an EISC server
|
||||||
|
/// eiscapiadvancedclient - Create an EISC client
|
||||||
|
/// vceiscapiadv - Create a VC-4 EISC client
|
||||||
|
/// vceiscapiadvanced - Create a VC-4 EISC client
|
||||||
|
/// eiscapiadvudp - Create a standard EISC client over UDP
|
||||||
|
/// eiscapiadvancedudp - Create a standard EISC client over UDP
|
||||||
|
/// </remarks>
|
||||||
public class EiscApiAdvancedFactory : EssentialsDeviceFactory<EiscApiAdvanced>
|
public class EiscApiAdvancedFactory : EssentialsDeviceFactory<EiscApiAdvanced>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
public EiscApiAdvancedFactory()
|
public EiscApiAdvancedFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced", "eiscapiadvancedserver", "eiscapiadvancedclient", "vceiscapiadv", "vceiscapiadvanced" };
|
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced", "eiscapiadvancedserver", "eiscapiadvancedclient", "vceiscapiadv", "vceiscapiadvanced", "eiscapiadvudp", "eiscapiadvancedudp" };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// BuildDevice method
|
|
||||||
/// </summary>
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new EiscApiAdvanced Device");
|
Debug.LogDebug("Attempting to create new EiscApiAdvanced Device");
|
||||||
|
|
||||||
var controlProperties = CommFactory.GetControlPropertiesConfig(dc);
|
var controlProperties = CommFactory.GetControlPropertiesConfig(dc);
|
||||||
|
|
||||||
@@ -449,6 +465,13 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
|
|
||||||
switch (dc.Type.ToLower())
|
switch (dc.Type.ToLower())
|
||||||
{
|
{
|
||||||
|
case "eiscapiadvudp":
|
||||||
|
case "eiscapiadvancedudp":
|
||||||
|
{
|
||||||
|
eisc = new EthernetIntersystemCommunications(controlProperties.IpIdInt,
|
||||||
|
controlProperties.TcpSshProperties.Address, Global.ControlSystem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "eiscapiadv":
|
case "eiscapiadv":
|
||||||
case "eiscapiadvanced":
|
case "eiscapiadvanced":
|
||||||
{
|
{
|
||||||
@@ -471,7 +494,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(controlProperties.RoomId))
|
if (string.IsNullOrEmpty(controlProperties.RoomId))
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Unable to build VC-4 EISC Client for device {0}. Room ID is missing or empty", dc.Key);
|
Debug.LogInformation("Unable to build VC-4 EISC Client for device {deviceKey}. Room ID is missing or empty", dc.Key);
|
||||||
eisc = null;
|
eisc = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using PepperDash.Essentials.Core.Devices;
|
using PepperDash.Core;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
//using PepperDash.Essentials.Devices.Common.Cameras;
|
//using PepperDash.Essentials.Devices.Common.Cameras;
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBridgeAdvanced
|
public interface IBridgeAdvanced
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Links the bridge to the API using the provided trilist, join start, join map key, and bridge.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="trilist">The trilist to link to.</param>
|
||||||
|
/// <param name="joinStart">The starting join number.</param>
|
||||||
|
/// <param name="joinMapKey">The key for the join map.</param>
|
||||||
|
/// <param name="bridge">The EISC API bridge.</param>
|
||||||
void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
|
void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a AirMediaControllerJoinMap
|
/// Represents a AirMediaControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a AppleTvJoinMap
|
/// Represents a AppleTvJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a C2nRthsControllerJoinMap
|
/// Represents a C2nRthsControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a CameraControllerJoinMap
|
/// Represents a CameraControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a CenOdtOccupancySensorBaseJoinMap
|
/// Represents a CenOdtOccupancySensorBaseJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a DisplayControllerJoinMap
|
/// Represents a DisplayControllerJoinMap
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges {
|
||||||
{
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a DmBladeChassisControllerJoinMap
|
/// Represents a DmBladeChassisControllerJoinMap
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a DmChassisControllerJoinMap
|
/// Represents a DmChassisControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a DmRmcControllerJoinMap
|
/// Represents a DmRmcControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a DmTxControllerJoinMap
|
/// Represents a DmTxControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a DmpsAudioOutputControllerJoinMap
|
/// Represents a DmpsAudioOutputControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a DmpsMicrophoneControllerJoinMap
|
/// Represents a DmpsMicrophoneControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a DmpsRoutingControllerJoinMap
|
/// Represents a DmpsRoutingControllerJoinMap
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a GenericLightingJoinMap
|
/// Represents a GenericLightingJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a GenericRelayControllerJoinMap
|
/// Represents a GenericRelayControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a GlsOccupancySensorBaseJoinMap
|
/// Represents a GlsOccupancySensorBaseJoinMap
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a HdMdNxM4kEControllerJoinMap
|
/// Represents a HdMdNxM4kEControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a HdMdxxxCEControllerJoinMap
|
/// Represents a HdMdxxxCEControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a HdPsXxxControllerJoinMap
|
/// Represents a HdPsXxxControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a Hrxxx0WirelessRemoteControllerJoinMap
|
/// Represents a Hrxxx0WirelessRemoteControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a IAnalogInputJoinMap
|
/// Represents a IAnalogInputJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a IBasicCommunicationJoinMap
|
/// Represents a IBasicCommunicationJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a IDigitalInputJoinMap
|
/// Represents a IDigitalInputJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a IDigitalOutputJoinMap
|
/// Represents a IDigitalOutputJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Join map for IRBlurayBase devices
|
/// Join map for IRBlurayBase devices
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a PduJoinMapBase
|
/// Represents a PduJoinMapBase
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a SetTopBoxControllerJoinMap
|
/// Represents a SetTopBoxControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a StatusSignControllerJoinMap
|
/// Represents a StatusSignControllerJoinMap
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a SystemMonitorJoinMap
|
/// Represents a SystemMonitorJoinMap
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using PepperDash.Essentials.Core.JoinMaps;
|
|
||||||
using System;
|
using System;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Crestron.SimplSharpPro;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Bridges
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Helper class for various Sig events
|
|
||||||
/// </summary>
|
|
||||||
public class SigHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Runs action when Sig is pressed
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sig"></param>
|
|
||||||
public static void Pressed(Sig sig, Action act) { if (sig.BoolValue) act(); }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Runs action when Sig is released
|
|
||||||
/// </summary>
|
|
||||||
public static void Released(Sig sig, Action act) { if (!sig.BoolValue) act(); }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SetBoolOutAction method
|
|
||||||
/// </summary>
|
|
||||||
public static void SetBoolOutAction(BoolOutputSig sig, Action<bool> a)
|
|
||||||
{
|
|
||||||
if (sig != null)
|
|
||||||
sig.UserObject = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Safely clears action of non-null sig.
|
|
||||||
/// </summary>
|
|
||||||
public static void ClearBoolOutAction(BoolOutputSig sig)
|
|
||||||
{
|
|
||||||
if (sig != null)
|
|
||||||
sig.UserObject = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Does a timed ramp, where the time is scaled proportional to the
|
|
||||||
/// remaining range to cover
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sig">Ushort sig to scale</param>
|
|
||||||
/// <param name="newLevel">Level to go to</param>
|
|
||||||
/// <param name="time">In ms (not hundredths like Crestron Sig ramp function)</param>
|
|
||||||
/// <summary>
|
|
||||||
/// RampTimeScaled method
|
|
||||||
/// </summary>
|
|
||||||
public static void RampTimeScaled(Sig sig, ushort newLevel, uint time)
|
|
||||||
{
|
|
||||||
var level = sig.UShortValue;
|
|
||||||
var diff = Math.Abs(level - newLevel);
|
|
||||||
var scaledTime = (uint)(diff * time / 65535);
|
|
||||||
Ramp(sig, newLevel, scaledTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ramps signal
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sig"></param>
|
|
||||||
/// <param name="level"></param>
|
|
||||||
/// <param name="time">In ms (not hundredths like Crestron Sig ramp function)</param>
|
|
||||||
/// <summary>
|
|
||||||
/// Ramp method
|
|
||||||
/// </summary>
|
|
||||||
public static void Ramp(Sig sig, ushort level, uint time)
|
|
||||||
{
|
|
||||||
sig.CreateRamp(level, time / 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,26 @@
|
|||||||
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.SimplSharpPro;
|
||||||
using Crestron.SimplSharpPro.DM;
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
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;
|
||||||
@@ -27,16 +33,16 @@ namespace PepperDash.Essentials.Core.Communications
|
|||||||
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(() =>
|
||||||
{
|
{
|
||||||
Port = postActivationFunc(config);
|
Port = postActivationFunc(config);
|
||||||
|
|
||||||
Port.StreamCec.CecChange += StreamCec_CecChange;
|
Port.StreamCec.CecChange += StreamCec_CecChange;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public CecPortController(string key, ICec port)
|
public CecPortController(string key, ICec port)
|
||||||
@@ -52,27 +58,25 @@ namespace PepperDash.Essentials.Core.Communications
|
|||||||
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
|
||||||
@@ -84,8 +88,7 @@ namespace PepperDash.Essentials.Core.Communications
|
|||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,8 +100,8 @@ namespace PepperDash.Essentials.Core.Communications
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +136,7 @@ namespace PepperDash.Essentials.Core.Communications
|
|||||||
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);
|
||||||
}
|
}
|
||||||
228
src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs
Normal file
228
src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.GeneralIO;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Core.Logging;
|
||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a ComPortController
|
||||||
|
/// </summary>
|
||||||
|
public class ComPortController : Device, IBasicCommunicationWithStreamDebugging
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the StreamDebugging
|
||||||
|
/// </summary>
|
||||||
|
public CommunicationStreamDebugging StreamDebugging { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when bytes are received
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when text is received
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the IsConnected
|
||||||
|
/// </summary>
|
||||||
|
public bool IsConnected { get { return true; } }
|
||||||
|
|
||||||
|
ComPort Port;
|
||||||
|
ComPort.ComPortSpec Spec;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <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;
|
||||||
|
|
||||||
|
AddPostActivationAction(() =>
|
||||||
|
{
|
||||||
|
Port = postActivationFunc(config);
|
||||||
|
|
||||||
|
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)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
if (port == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, this, "ERROR: Invalid com port, continuing but comms will not function");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Port = port;
|
||||||
|
Spec = spec;
|
||||||
|
//IsConnected = new BoolFeedback(CommonBoolCue.IsConnected, () => true);
|
||||||
|
|
||||||
|
RegisterAndConfigureComPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterAndConfigureComPort()
|
||||||
|
{
|
||||||
|
if (Port == null)
|
||||||
|
{
|
||||||
|
this.LogInformation($"Configured {Port.Parent.GetType().Name}-comport-{Port.ID} for {Key} does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Port_SerialDataReceived(ComPort ReceivingComPort, ComPortSerialDataEventArgs args)
|
||||||
|
{
|
||||||
|
OnDataReceived(args.SerialData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDataReceived(string s)
|
||||||
|
{
|
||||||
|
var eventSubscribed = false;
|
||||||
|
|
||||||
|
var bytesHandler = BytesReceived;
|
||||||
|
if (bytesHandler != null)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
|
||||||
|
this.PrintReceivedBytes(bytes);
|
||||||
|
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||||
|
eventSubscribed = true;
|
||||||
|
}
|
||||||
|
var textHandler = TextReceived;
|
||||||
|
if (textHandler != null)
|
||||||
|
{
|
||||||
|
this.PrintReceivedText(s);
|
||||||
|
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
||||||
|
eventSubscribed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eventSubscribed) Debug.LogMessage(LogEventLevel.Warning, this, "Received data but no handler is registered");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deactivate method
|
||||||
|
/// </summary>
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool Deactivate()
|
||||||
|
{
|
||||||
|
return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IBasicCommunication Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SendText method
|
||||||
|
/// </summary>
|
||||||
|
public void SendText(string text)
|
||||||
|
{
|
||||||
|
if (Port == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.PrintSentText(text);
|
||||||
|
Port.Send(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SendBytes method
|
||||||
|
/// </summary>
|
||||||
|
public void SendBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (Port == null)
|
||||||
|
return;
|
||||||
|
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
||||||
|
this.PrintSentBytes(bytes);
|
||||||
|
|
||||||
|
Port.Send(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connect method
|
||||||
|
/// </summary>
|
||||||
|
public void Connect()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disconnect method
|
||||||
|
/// </summary>
|
||||||
|
public void Disconnect()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
/// <summary>
|
||||||
|
/// SimulateReceive method
|
||||||
|
/// </summary>
|
||||||
|
public void SimulateReceive(string s)
|
||||||
|
{
|
||||||
|
// split out hex chars and build string
|
||||||
|
var split = Regex.Split(s, @"(\\[Xx][0-9a-fA-F][0-9a-fA-F])");
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
foreach (var t in split)
|
||||||
|
{
|
||||||
|
if (t.StartsWith(@"\") && t.Length == 4)
|
||||||
|
b.Append((char)(Convert.ToByte(t.Substring(2, 2), 16)));
|
||||||
|
else
|
||||||
|
b.Append(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnDataReceived(b.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,19 @@
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
using Crestron.SimplSharpPro;
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This converter creates a proper ComPort.ComPortSpec struct from more-friendly JSON values. It uses
|
/// This converter creates a proper ComPort.ComPortSpec struct from more-friendly JSON values. It uses
|
||||||
138
src/PepperDash.Essentials.Core/Comm and IR/CommBridge.cs
Normal file
138
src/PepperDash.Essentials.Core/Comm and IR/CommBridge.cs
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp.CrestronSockets;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Core.Logging;
|
||||||
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Core.Devices;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implements IBasicCommunication and sends all communication through an EISC
|
||||||
|
/// </summary>
|
||||||
|
[Description("Generic communication wrapper class for any IBasicCommunication type")]
|
||||||
|
public class CommBridge : EssentialsBridgeableDevice, IBasicCommunication
|
||||||
|
{
|
||||||
|
private EiscApiAdvanced eisc;
|
||||||
|
|
||||||
|
private IBasicCommunicationJoinMap joinMap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when text is received through the communication bridge.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when bytes are received through the communication bridge.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether the communication bridge is currently connected.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsConnected { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CommBridge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The unique key for the communication bridge.</param>
|
||||||
|
/// <param name="name">The display name for the communication bridge.</param>
|
||||||
|
public CommBridge(string key, string name)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a byte array through the communication bridge.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">The byte array to send.</param>
|
||||||
|
public void SendBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (eisc == null)
|
||||||
|
{
|
||||||
|
this.LogWarning("EISC is null, cannot send bytes.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eisc.Eisc.SetString(joinMap.SendText.JoinNumber, Encoding.ASCII.GetString(bytes, 0, bytes.Length));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a text string through the communication bridge.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">The text string to send.</param>
|
||||||
|
public void SendText(string text)
|
||||||
|
{
|
||||||
|
if (eisc == null)
|
||||||
|
{
|
||||||
|
this.LogWarning("EISC is null, cannot send text.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eisc.Eisc.SetString(joinMap.SendText.JoinNumber, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initiates a connection through the communication bridge.
|
||||||
|
/// </summary>
|
||||||
|
public void Connect()
|
||||||
|
{
|
||||||
|
if (eisc == null)
|
||||||
|
{
|
||||||
|
this.LogWarning("EISC is null, cannot connect.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eisc.Eisc.SetBool(joinMap.Connect.JoinNumber, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Terminates the connection through the communication bridge.
|
||||||
|
/// </summary>
|
||||||
|
public void Disconnect()
|
||||||
|
{
|
||||||
|
if (eisc == null)
|
||||||
|
{
|
||||||
|
this.LogWarning("EISC is null, cannot disconnect.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eisc.Eisc.SetBool(joinMap.Connect.JoinNumber, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||||
|
{
|
||||||
|
joinMap = new IBasicCommunicationJoinMap(joinStart);
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<IBasicCommunicationJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
if (bridge != null)
|
||||||
|
{
|
||||||
|
bridge.AddJoinMap(Key, joinMap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
eisc = bridge;
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(joinMap.Connected.JoinNumber, (b) => IsConnected = b);
|
||||||
|
|
||||||
|
trilist.SetStringSigAction(joinMap.TextReceived.JoinNumber, (s) =>
|
||||||
|
{
|
||||||
|
TextReceived?.Invoke(this, new GenericCommMethodReceiveTextArgs(s));
|
||||||
|
BytesReceived?.Invoke(this, new GenericCommMethodReceiveBytesArgs(Encoding.ASCII.GetBytes(s)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
297
src/PepperDash.Essentials.Core/Comm and IR/CommFactory.cs
Normal file
297
src/PepperDash.Essentials.Core/Comm and IR/CommFactory.cs
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class CommFactory
|
||||||
|
{
|
||||||
|
public static EssentialsControlPropertiesConfig GetControlPropertiesConfig(DeviceConfig deviceConfig)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return JsonConvert.DeserializeObject<EssentialsControlPropertiesConfig>
|
||||||
|
(deviceConfig.Properties["control"].ToString());
|
||||||
|
//Debug.LogMessage(LogEventLevel.Verbose, "Control TEST: {0}", JsonConvert.SerializeObject(controlConfig));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "ERROR: [{0}] Control properties deserialize failed:\r{1}", deviceConfig.Key, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a comm method of either com port, TCP, SSH, and puts this into the DeviceManager
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deviceConfig">The Device config object</param>
|
||||||
|
/// <summary>
|
||||||
|
/// CreateCommForDevice method
|
||||||
|
/// </summary>
|
||||||
|
public static IBasicCommunication CreateCommForDevice(DeviceConfig deviceConfig)
|
||||||
|
{
|
||||||
|
EssentialsControlPropertiesConfig controlConfig = GetControlPropertiesConfig(deviceConfig);
|
||||||
|
if (controlConfig == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
IBasicCommunication comm = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var c = controlConfig.TcpSshProperties;
|
||||||
|
switch (controlConfig.Method)
|
||||||
|
{
|
||||||
|
case eControlMethod.Com:
|
||||||
|
comm = new ComPortController(deviceConfig.Key + "-com", GetComPort, controlConfig.ComParams.Value, controlConfig);
|
||||||
|
break;
|
||||||
|
case eControlMethod.ComBridge:
|
||||||
|
comm = new CommBridge(deviceConfig.Key + "-simpl", deviceConfig.Name + " Simpl");
|
||||||
|
break;
|
||||||
|
case eControlMethod.Cec:
|
||||||
|
comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort, controlConfig);
|
||||||
|
break;
|
||||||
|
case eControlMethod.IR:
|
||||||
|
break;
|
||||||
|
case eControlMethod.Ssh:
|
||||||
|
{
|
||||||
|
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password)
|
||||||
|
{
|
||||||
|
AutoReconnect = c.AutoReconnect,
|
||||||
|
DisableEcho = c.DisableSshEcho
|
||||||
|
};
|
||||||
|
if (ssh.AutoReconnect)
|
||||||
|
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||||
|
comm = ssh;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eControlMethod.Tcpip:
|
||||||
|
{
|
||||||
|
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize)
|
||||||
|
{
|
||||||
|
AutoReconnect = c.AutoReconnect
|
||||||
|
};
|
||||||
|
if (tcp.AutoReconnect)
|
||||||
|
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||||
|
comm = tcp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eControlMethod.Udp:
|
||||||
|
{
|
||||||
|
var udp = new GenericUdpServer(deviceConfig.Key + "-udp", c.Address, c.Port, c.BufferSize);
|
||||||
|
comm = udp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eControlMethod.Telnet:
|
||||||
|
break;
|
||||||
|
case eControlMethod.SecureTcpIp:
|
||||||
|
{
|
||||||
|
var secureTcp = new GenericSecureTcpIpClient(deviceConfig.Key + "-secureTcp", c.Address, c.Port, c.BufferSize)
|
||||||
|
{
|
||||||
|
AutoReconnect = c.AutoReconnect
|
||||||
|
};
|
||||||
|
if (secureTcp.AutoReconnect)
|
||||||
|
secureTcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||||
|
comm = secureTcp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "Cannot create communication from JSON:\r{0}\r\rException:\r{1}",
|
||||||
|
deviceConfig.Properties.ToString(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// put it in the device manager if it's the right flavor
|
||||||
|
if (comm is Device comDev)
|
||||||
|
DeviceManager.AddDevice(comDev);
|
||||||
|
return comm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GetComPort method
|
||||||
|
/// </summary>
|
||||||
|
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
|
||||||
|
{
|
||||||
|
var comPar = config.ComParams;
|
||||||
|
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
|
||||||
|
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
|
||||||
|
return dev.ComPorts[config.ControlPortNumber.Value];
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an ICec port from a RoutingInput or RoutingOutput on a device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <summary>
|
||||||
|
/// GetCecPort method
|
||||||
|
/// </summary>
|
||||||
|
public static ICec GetCecPort(ControlPropertiesConfig config)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey);
|
||||||
|
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: device '{0}' {1}", config.ControlPortDevKey, dev == null
|
||||||
|
? "is not valid, failed to get cec port"
|
||||||
|
: "found in device manager, attempting to get cec port");
|
||||||
|
|
||||||
|
if (dev == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(config.ControlPortName))
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var inputsOutputs = dev as IRoutingInputsOutputs;
|
||||||
|
if (inputsOutputs == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: Device '{0}' does not support IRoutingInputsOutputs, failed to get CEC port called '{1}'",
|
||||||
|
config.ControlPortDevKey, config.ControlPortName);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var inputPort = inputsOutputs.InputPorts[config.ControlPortName];
|
||||||
|
if (inputPort != null && inputPort.Port is ICec)
|
||||||
|
return inputPort.Port as ICec;
|
||||||
|
|
||||||
|
|
||||||
|
var outputPort = inputsOutputs.OutputPorts[config.ControlPortName];
|
||||||
|
if (outputPort != null && outputPort.Port is ICec)
|
||||||
|
return outputPort.Port as ICec;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Debug, "GetCecPort Exception Message: {0}", ex.Message);
|
||||||
|
Debug.LogMessage(LogEventLevel.Verbose, "GetCecPort Exception StackTrace: {0}", ex.StackTrace);
|
||||||
|
if (ex.InnerException != null)
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "GetCecPort Exception InnerException: {0}", ex.InnerException);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: Device '{0}' does not have a CEC port called '{1}'",
|
||||||
|
config.ControlPortDevKey, config.ControlPortName);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to grab the IComPorts device for this PortDeviceKey. Key "controlSystem" will
|
||||||
|
/// return the ControlSystem object from the Global class.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>IComPorts device or null if the device is not found or does not implement IComPorts</returns>
|
||||||
|
/// <summary>
|
||||||
|
/// GetIComPortsDeviceFromManagedDevice method
|
||||||
|
/// </summary>
|
||||||
|
public static IComPorts GetIComPortsDeviceFromManagedDevice(string ComPortDevKey)
|
||||||
|
{
|
||||||
|
if ((ComPortDevKey.Equals("controlSystem", System.StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| ComPortDevKey.Equals("processor", System.StringComparison.OrdinalIgnoreCase))
|
||||||
|
&& Global.ControlSystem is IComPorts)
|
||||||
|
return Global.ControlSystem;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(ComPortDevKey) as IComPorts;
|
||||||
|
if (dev == null)
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "ComPortConfig: Cannot find com port device '{0}'", ComPortDevKey);
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a EssentialsControlPropertiesConfig
|
||||||
|
/// </summary>
|
||||||
|
public class EssentialsControlPropertiesConfig :
|
||||||
|
ControlPropertiesConfig
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonProperty("comParams", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
[JsonConverter(typeof(ComSpecJsonConverter))]
|
||||||
|
public ComPort.ComPortSpec? ComParams { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("cresnetId", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public string CresnetId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to provide uint conversion of string CresnetId
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public uint CresnetIdInt
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Convert.ToUInt32(CresnetId, 16);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw new FormatException(string.Format("ERROR:Unable to convert Cresnet ID: {0} to hex. Error:\n{1}", CresnetId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty("infinetId", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the InfinetId
|
||||||
|
/// </summary>
|
||||||
|
public string InfinetId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attepmts to provide uiont conversion of string InifinetId
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public uint InfinetIdInt
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Convert.ToUInt32(InfinetId, 16);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw new FormatException(string.Format("ERROR:Unable to conver Infinet ID: {0} to hex. Error:\n{1}", InfinetId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a IrControlSpec
|
||||||
|
/// </summary>
|
||||||
|
public class IrControlSpec
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the PortDeviceKey
|
||||||
|
/// </summary>
|
||||||
|
public string PortDeviceKey { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the PortNumber
|
||||||
|
/// </summary>
|
||||||
|
public uint PortNumber { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the File
|
||||||
|
/// </summary>
|
||||||
|
public string File { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface IComPortsDevice
|
||||||
|
{
|
||||||
|
IComPorts Device { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.Devices;
|
|
||||||
using PepperDash.Essentials.Core.Monitoring;
|
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a ConsoleCommMockDevice
|
/// Represents a ConsoleCommMockDevice
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Crestron.SimplSharp.CrestronSockets;
|
using Crestron.SimplSharp.CrestronSockets;
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.Core.Devices;
|
using PepperDash.Essentials.Core.Devices;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using PepperDash.Essentials.Core.Bridges.JoinMaps;
|
|
||||||
using PepperDash.Essentials.Core.JoinMaps;
|
|
||||||
using PepperDash.Essentials.Core.Config.Essentials;
|
|
||||||
using PepperDash.Essentials.Core.Touchpanels;
|
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serves as a generic wrapper class for all styles of IBasicCommuncation ports
|
/// Serves as a generic wrapper class for all styles of IBasicCommuncation ports
|
||||||
@@ -120,7 +120,7 @@ namespace PepperDash.Essentials.Core.Communications
|
|||||||
if (sComm == null) return;
|
if (sComm == null) return;
|
||||||
sComm.ConnectionChange += (s, a) =>
|
sComm.ConnectionChange += (s, a) =>
|
||||||
{
|
{
|
||||||
trilist.SetUshort(joinMap.Status.JoinNumber, (ushort)a.Client.ClientStatus);
|
trilist.SetUshort(joinMap.Status.JoinNumber, (ushort)(a.Client.ClientStatus));
|
||||||
trilist.SetBool(joinMap.Connected.JoinNumber, a.Client.ClientStatus ==
|
trilist.SetBool(joinMap.Connected.JoinNumber, a.Client.ClientStatus ==
|
||||||
SocketStatus.SOCKET_STATUS_CONNECTED);
|
SocketStatus.SOCKET_STATUS_CONNECTED);
|
||||||
};
|
};
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
using Crestron.SimplSharp.Net.Http;
|
using Crestron.SimplSharp.Net.Http;
|
||||||
|
using PepperDash.Core;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
[Obsolete("Please use the builtin HttpClient class instead: https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines")]
|
[Obsolete("Please use the builtin HttpClient class instead: https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -32,17 +33,17 @@ namespace PepperDash.Essentials.Core.Communications
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendText(string path)
|
public void SendText(string path)
|
||||||
{
|
{
|
||||||
var request = new HttpClientRequest();
|
HttpClientRequest request = new HttpClientRequest();
|
||||||
var url = string.Format("http://{0}/{1}", Client.HostName, path);
|
string url = string.Format("http://{0}/{1}", Client.HostName, path);
|
||||||
request.Url = new UrlParser(url);
|
request.Url = new UrlParser(url);
|
||||||
var error = Client.DispatchAsyncEx(request, Response, request);
|
HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request);
|
||||||
}
|
}
|
||||||
public void SendText(string format, params object[] items)
|
public void SendText(string format, params object[] items)
|
||||||
{
|
{
|
||||||
var request = new HttpClientRequest();
|
HttpClientRequest request = new HttpClientRequest();
|
||||||
var url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
|
string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
|
||||||
request.Url = new UrlParser(url);
|
request.Url = new UrlParser(url);
|
||||||
var error = Client.DispatchAsyncEx(request, Response, request);
|
HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -50,8 +51,8 @@ namespace PepperDash.Essentials.Core.Communications
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendTextNoResponse(string format, params object[] items)
|
public void SendTextNoResponse(string format, params object[] items)
|
||||||
{
|
{
|
||||||
var request = new HttpClientRequest();
|
HttpClientRequest request = new HttpClientRequest();
|
||||||
var url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
|
string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
|
||||||
request.Url = new UrlParser(url);
|
request.Url = new UrlParser(url);
|
||||||
Client.Dispatch(request);
|
Client.Dispatch(request);
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,18 @@
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
using Crestron.SimplSharpPro;
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.Devices;
|
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
@@ -1,200 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Crestron.SimplSharpPro;
|
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a ComPortController
|
|
||||||
/// </summary>
|
|
||||||
public class ComPortController : Device, IBasicCommunicationWithStreamDebugging
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the StreamDebugging
|
|
||||||
/// </summary>
|
|
||||||
public CommunicationStreamDebugging StreamDebugging { get; private set; }
|
|
||||||
|
|
||||||
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
|
||||||
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the IsConnected
|
|
||||||
/// </summary>
|
|
||||||
public bool IsConnected { get { return true; } }
|
|
||||||
|
|
||||||
ComPort Port;
|
|
||||||
ComPort.ComPortSpec Spec;
|
|
||||||
|
|
||||||
public ComPortController(string key, Func<EssentialsControlPropertiesConfig, ComPort> postActivationFunc,
|
|
||||||
ComPort.ComPortSpec spec, EssentialsControlPropertiesConfig config) : base(key)
|
|
||||||
{
|
|
||||||
StreamDebugging = new CommunicationStreamDebugging(key);
|
|
||||||
|
|
||||||
Spec = spec;
|
|
||||||
|
|
||||||
AddPostActivationAction(() =>
|
|
||||||
{
|
|
||||||
Port = postActivationFunc(config);
|
|
||||||
|
|
||||||
RegisterAndConfigureComPort();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public ComPortController(string key, ComPort port, ComPort.ComPortSpec spec)
|
|
||||||
: base(key)
|
|
||||||
{
|
|
||||||
if (port == null)
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "ERROR: Invalid com port, continuing but comms will not function");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Port = port;
|
|
||||||
Spec = spec;
|
|
||||||
//IsConnected = new BoolFeedback(CommonBoolCue.IsConnected, () => true);
|
|
||||||
|
|
||||||
RegisterAndConfigureComPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RegisterAndConfigureComPort()
|
|
||||||
{
|
|
||||||
if (Port == null)
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Configured com Port for this device does not exist.");
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
Port.SerialDataReceived -= Port_SerialDataReceived;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Port_SerialDataReceived(ComPort ReceivingComPort, ComPortSerialDataEventArgs args)
|
|
||||||
{
|
|
||||||
OnDataReceived(args.SerialData);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnDataReceived(string s)
|
|
||||||
{
|
|
||||||
var eventSubscribed = false;
|
|
||||||
|
|
||||||
var bytesHandler = BytesReceived;
|
|
||||||
if (bytesHandler != null)
|
|
||||||
{
|
|
||||||
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
|
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Received: '{0}'", ComTextHelper.GetEscapedText(bytes));
|
|
||||||
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
|
||||||
eventSubscribed = true;
|
|
||||||
}
|
|
||||||
var textHandler = TextReceived;
|
|
||||||
if (textHandler != null)
|
|
||||||
{
|
|
||||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Received: '{0}'", s);
|
|
||||||
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
|
||||||
eventSubscribed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!eventSubscribed) Debug.LogMessage(LogEventLevel.Warning, this, "Received data but no handler is registered");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deactivate method
|
|
||||||
/// </summary>
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override bool Deactivate()
|
|
||||||
{
|
|
||||||
return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IBasicCommunication Members
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SendText method
|
|
||||||
/// </summary>
|
|
||||||
public void SendText(string text)
|
|
||||||
{
|
|
||||||
if (Port == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Sending {0} characters of text: '{1}'", text.Length, text);
|
|
||||||
Port.Send(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SendBytes method
|
|
||||||
/// </summary>
|
|
||||||
public void SendBytes(byte[] bytes)
|
|
||||||
{
|
|
||||||
if (Port == null)
|
|
||||||
return;
|
|
||||||
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
|
||||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
|
||||||
|
|
||||||
Port.Send(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Connect method
|
|
||||||
/// </summary>
|
|
||||||
public void Connect()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disconnect method
|
|
||||||
/// </summary>
|
|
||||||
public void Disconnect()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="s"></param>
|
|
||||||
/// <summary>
|
|
||||||
/// SimulateReceive method
|
|
||||||
/// </summary>
|
|
||||||
public void SimulateReceive(string s)
|
|
||||||
{
|
|
||||||
// split out hex chars and build string
|
|
||||||
var split = Regex.Split(s, @"(\\[Xx][0-9a-fA-F][0-9a-fA-F])");
|
|
||||||
var b = new StringBuilder();
|
|
||||||
foreach (var t in split)
|
|
||||||
{
|
|
||||||
if (t.StartsWith(@"\") && t.Length == 4)
|
|
||||||
b.Append((char)Convert.ToByte(t.Substring(2, 2), 16));
|
|
||||||
else
|
|
||||||
b.Append(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnDataReceived(b.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public class ComTextHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets escaped text for a byte array
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes"></param>
|
|
||||||
/// <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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,289 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using Crestron.SimplSharpPro;
|
|
||||||
using Crestron.SimplSharpPro.DM;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using PepperDash.Essentials.Core.Config;
|
|
||||||
using PepperDash.Essentials.Core.Devices;
|
|
||||||
using PepperDash.Essentials.Core.Routing;
|
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public class CommFactory
|
|
||||||
{
|
|
||||||
public static EssentialsControlPropertiesConfig GetControlPropertiesConfig(DeviceConfig deviceConfig)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return JsonConvert.DeserializeObject<EssentialsControlPropertiesConfig>
|
|
||||||
(deviceConfig.Properties["control"].ToString());
|
|
||||||
//Debug.LogMessage(LogEventLevel.Verbose, "Control TEST: {0}", JsonConvert.SerializeObject(controlConfig));
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "ERROR: [{0}] Control properties deserialize failed:\r{1}", deviceConfig.Key, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a comm method of either com port, TCP, SSH, and puts this into the DeviceManager
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="deviceConfig">The Device config object</param>
|
|
||||||
/// <summary>
|
|
||||||
/// CreateCommForDevice method
|
|
||||||
/// </summary>
|
|
||||||
public static IBasicCommunication CreateCommForDevice(DeviceConfig deviceConfig)
|
|
||||||
{
|
|
||||||
EssentialsControlPropertiesConfig controlConfig = GetControlPropertiesConfig(deviceConfig);
|
|
||||||
if (controlConfig == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
IBasicCommunication comm = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var c = controlConfig.TcpSshProperties;
|
|
||||||
switch (controlConfig.Method)
|
|
||||||
{
|
|
||||||
case eControlMethod.Com:
|
|
||||||
comm = new ComPortController(deviceConfig.Key + "-com", GetComPort, controlConfig.ComParams.Value, controlConfig);
|
|
||||||
break;
|
|
||||||
case eControlMethod.Cec:
|
|
||||||
comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort, controlConfig);
|
|
||||||
break;
|
|
||||||
case eControlMethod.IR:
|
|
||||||
break;
|
|
||||||
case eControlMethod.Ssh:
|
|
||||||
{
|
|
||||||
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password);
|
|
||||||
ssh.AutoReconnect = c.AutoReconnect;
|
|
||||||
if(ssh.AutoReconnect)
|
|
||||||
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
|
||||||
comm = ssh;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case eControlMethod.Tcpip:
|
|
||||||
{
|
|
||||||
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize);
|
|
||||||
tcp.AutoReconnect = c.AutoReconnect;
|
|
||||||
if (tcp.AutoReconnect)
|
|
||||||
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
|
||||||
comm = tcp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case eControlMethod.Udp:
|
|
||||||
{
|
|
||||||
var udp = new GenericUdpServer(deviceConfig.Key + "-udp", c.Address, c.Port, c.BufferSize);
|
|
||||||
comm = udp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case eControlMethod.Telnet:
|
|
||||||
break;
|
|
||||||
case eControlMethod.SecureTcpIp:
|
|
||||||
{
|
|
||||||
var secureTcp = new GenericSecureTcpIpClient(deviceConfig.Key + "-secureTcp", c.Address, c.Port, c.BufferSize);
|
|
||||||
secureTcp.AutoReconnect = c.AutoReconnect;
|
|
||||||
if (secureTcp.AutoReconnect)
|
|
||||||
secureTcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
|
||||||
comm = secureTcp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Cannot create communication from JSON:\r{0}\r\rException:\r{1}",
|
|
||||||
deviceConfig.Properties.ToString(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// put it in the device manager if it's the right flavor
|
|
||||||
var comDev = comm as Device;
|
|
||||||
if (comDev != null)
|
|
||||||
DeviceManager.AddDevice(comDev);
|
|
||||||
return comm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// GetComPort method
|
|
||||||
/// </summary>
|
|
||||||
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
|
|
||||||
{
|
|
||||||
var comPar = config.ComParams;
|
|
||||||
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
|
|
||||||
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
|
|
||||||
return dev.ComPorts[config.ControlPortNumber.Value];
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets an ICec port from a RoutingInput or RoutingOutput on a device
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="config"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <summary>
|
|
||||||
/// GetCecPort method
|
|
||||||
/// </summary>
|
|
||||||
public static ICec GetCecPort(ControlPropertiesConfig config)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey);
|
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: device '{0}' {1}", config.ControlPortDevKey, dev == null
|
|
||||||
? "is not valid, failed to get cec port"
|
|
||||||
: "found in device manager, attempting to get cec port");
|
|
||||||
|
|
||||||
if (dev == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(config.ControlPortName))
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var inputsOutputs = dev as IRoutingInputsOutputs;
|
|
||||||
if (inputsOutputs == null)
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: Device '{0}' does not support IRoutingInputsOutputs, failed to get CEC port called '{1}'",
|
|
||||||
config.ControlPortDevKey, config.ControlPortName);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var inputPort = inputsOutputs.InputPorts[config.ControlPortName];
|
|
||||||
if (inputPort != null && inputPort.Port is ICec)
|
|
||||||
return inputPort.Port as ICec;
|
|
||||||
|
|
||||||
|
|
||||||
var outputPort = inputsOutputs.OutputPorts[config.ControlPortName];
|
|
||||||
if (outputPort != null && outputPort.Port is ICec)
|
|
||||||
return outputPort.Port as ICec;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "GetCecPort Exception Message: {0}", ex.Message);
|
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "GetCecPort Exception StackTrace: {0}", ex.StackTrace);
|
|
||||||
if (ex.InnerException != null)
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "GetCecPort Exception InnerException: {0}", ex.InnerException);
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: Device '{0}' does not have a CEC port called '{1}'",
|
|
||||||
config.ControlPortDevKey, config.ControlPortName);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Helper to grab the IComPorts device for this PortDeviceKey. Key "controlSystem" will
|
|
||||||
/// return the ControlSystem object from the Global class.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>IComPorts device or null if the device is not found or does not implement IComPorts</returns>
|
|
||||||
/// <summary>
|
|
||||||
/// GetIComPortsDeviceFromManagedDevice method
|
|
||||||
/// </summary>
|
|
||||||
public static IComPorts GetIComPortsDeviceFromManagedDevice(string ComPortDevKey)
|
|
||||||
{
|
|
||||||
if ((ComPortDevKey.Equals("controlSystem", StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| ComPortDevKey.Equals("processor", StringComparison.OrdinalIgnoreCase))
|
|
||||||
&& Global.ControlSystem is IComPorts)
|
|
||||||
return Global.ControlSystem;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var dev = DeviceManager.GetDeviceForKey(ComPortDevKey) as IComPorts;
|
|
||||||
if (dev == null)
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "ComPortConfig: Cannot find com port device '{0}'", ComPortDevKey);
|
|
||||||
return dev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a EssentialsControlPropertiesConfig
|
|
||||||
/// </summary>
|
|
||||||
public class EssentialsControlPropertiesConfig :
|
|
||||||
ControlPropertiesConfig
|
|
||||||
{
|
|
||||||
|
|
||||||
[JsonProperty("comParams", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
[JsonConverter(typeof(ComSpecJsonConverter))]
|
|
||||||
public ComPort.ComPortSpec? ComParams { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("cresnetId", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public string CresnetId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to provide uint conversion of string CresnetId
|
|
||||||
/// </summary>
|
|
||||||
[JsonIgnore]
|
|
||||||
public uint CresnetIdInt
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Convert.ToUInt32(CresnetId, 16);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
throw new FormatException(string.Format("ERROR:Unable to convert Cresnet ID: {0} to hex. Error:\n{1}", CresnetId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty("infinetId", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the InfinetId
|
|
||||||
/// </summary>
|
|
||||||
public string InfinetId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attepmts to provide uiont conversion of string InifinetId
|
|
||||||
/// </summary>
|
|
||||||
[JsonIgnore]
|
|
||||||
public uint InfinetIdInt
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Convert.ToUInt32(InfinetId, 16);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
throw new FormatException(string.Format("ERROR:Unable to conver Infinet ID: {0} to hex. Error:\n{1}", InfinetId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a IrControlSpec
|
|
||||||
/// </summary>
|
|
||||||
public class IrControlSpec
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the PortDeviceKey
|
|
||||||
/// </summary>
|
|
||||||
public string PortDeviceKey { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the PortNumber
|
|
||||||
/// </summary>
|
|
||||||
public uint PortNumber { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the File
|
|
||||||
/// </summary>
|
|
||||||
public string File { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public enum eGenericCommMethodStatusChangeType
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Connected
|
|
||||||
/// </summary>
|
|
||||||
Connected,
|
|
||||||
/// <summary>
|
|
||||||
/// Disconnected
|
|
||||||
/// </summary>
|
|
||||||
Disconnected
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This delegate defines handler for IBasicCommunication status changes
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="comm">Device firing the status change</param>
|
|
||||||
/// <param name="status"></param>
|
|
||||||
public delegate void GenericCommMethodStatusHandler(IBasicCommunication comm, eGenericCommMethodStatusChangeType status);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public class GenericCommMethodReceiveBytesArgs : EventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the Bytes
|
|
||||||
/// </summary>
|
|
||||||
public byte[] Bytes { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes"></param>
|
|
||||||
public GenericCommMethodReceiveBytesArgs(byte[] bytes)
|
|
||||||
{
|
|
||||||
Bytes = bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// S+ Constructor
|
|
||||||
/// </summary>
|
|
||||||
public GenericCommMethodReceiveBytesArgs() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public class GenericCommMethodReceiveTextArgs : EventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string Text { get; private set; }
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string Delimiter { get; private set; }
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
public GenericCommMethodReceiveTextArgs(string text)
|
|
||||||
{
|
|
||||||
Text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
/// <param name="delimiter"></param>
|
|
||||||
public GenericCommMethodReceiveTextArgs(string text, string delimiter)
|
|
||||||
:this(text)
|
|
||||||
{
|
|
||||||
Delimiter = delimiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// S+ Constructor
|
|
||||||
/// </summary>
|
|
||||||
public GenericCommMethodReceiveTextArgs() { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,173 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Defines the string event handler for line events on the gather
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
public delegate void LineReceivedHandler(string text);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attaches to IBasicCommunication as a text gather
|
|
||||||
/// </summary>
|
|
||||||
public class CommunicationGather
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Event that fires when a line is received from the IBasicCommunication source.
|
|
||||||
/// The event merely contains the text, not an EventArgs type class.
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler<GenericCommMethodReceiveTextArgs> LineReceived;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The communication port that this gathers on
|
|
||||||
/// </summary>
|
|
||||||
public ICommunicationReceiver Port { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default false. If true, the delimiter will be included in the line output
|
|
||||||
/// events
|
|
||||||
/// </summary>
|
|
||||||
public bool IncludeDelimiter { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// For receive buffer
|
|
||||||
/// </summary>
|
|
||||||
StringBuilder ReceiveBuffer = new StringBuilder();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delimiter, like it says!
|
|
||||||
/// </summary>
|
|
||||||
char Delimiter;
|
|
||||||
|
|
||||||
string[] StringDelimiters;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor for using a char delimiter
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="port"></param>
|
|
||||||
/// <param name="delimiter"></param>
|
|
||||||
public CommunicationGather(ICommunicationReceiver port, char delimiter)
|
|
||||||
{
|
|
||||||
Port = port;
|
|
||||||
Delimiter = delimiter;
|
|
||||||
port.TextReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(Port_TextReceived);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor for using a single string delimiter
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="port"></param>
|
|
||||||
/// <param name="delimiter"></param>
|
|
||||||
public CommunicationGather(ICommunicationReceiver port, string delimiter)
|
|
||||||
:this(port, new string[] { delimiter} )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor for using an array of string delimiters
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="port"></param>
|
|
||||||
/// <param name="delimiters"></param>
|
|
||||||
public CommunicationGather(ICommunicationReceiver port, string[] delimiters)
|
|
||||||
{
|
|
||||||
Port = port;
|
|
||||||
StringDelimiters = delimiters;
|
|
||||||
port.TextReceived += Port_TextReceivedStringDelimiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Stop method
|
|
||||||
/// </summary>
|
|
||||||
public void Stop()
|
|
||||||
{
|
|
||||||
Port.TextReceived -= Port_TextReceived;
|
|
||||||
Port.TextReceived -= Port_TextReceivedStringDelimiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handler for raw data coming from port
|
|
||||||
/// </summary>
|
|
||||||
void Port_TextReceived(object sender, GenericCommMethodReceiveTextArgs args)
|
|
||||||
{
|
|
||||||
var handler = LineReceived;
|
|
||||||
if (handler != null)
|
|
||||||
{
|
|
||||||
ReceiveBuffer.Append(args.Text);
|
|
||||||
var str = ReceiveBuffer.ToString();
|
|
||||||
var lines = str.Split(Delimiter);
|
|
||||||
if (lines.Length > 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < lines.Length - 1; i++)
|
|
||||||
{
|
|
||||||
string strToSend = null;
|
|
||||||
if (IncludeDelimiter)
|
|
||||||
strToSend = lines[i] + Delimiter;
|
|
||||||
else
|
|
||||||
strToSend = lines[i];
|
|
||||||
handler(this, new GenericCommMethodReceiveTextArgs(strToSend));
|
|
||||||
}
|
|
||||||
ReceiveBuffer = new StringBuilder(lines[lines.Length - 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="args"></param>
|
|
||||||
void Port_TextReceivedStringDelimiter(object sender, GenericCommMethodReceiveTextArgs args)
|
|
||||||
{
|
|
||||||
var handler = LineReceived;
|
|
||||||
if (handler != null)
|
|
||||||
{
|
|
||||||
// Receive buffer should either be empty or not contain the delimiter
|
|
||||||
// If the line does not have a delimiter, append the
|
|
||||||
ReceiveBuffer.Append(args.Text);
|
|
||||||
var str = ReceiveBuffer.ToString();
|
|
||||||
|
|
||||||
// Case: Receiving DEVICE get version\x0d\0x0a+OK "value":"1234"\x0d\x0a
|
|
||||||
|
|
||||||
// RX: DEV
|
|
||||||
// Split: (1) "DEV"
|
|
||||||
// RX: I
|
|
||||||
// Split: (1) "DEVI"
|
|
||||||
// RX: CE get version
|
|
||||||
// Split: (1) "DEVICE get version"
|
|
||||||
// RX: \x0d\x0a+OK "value":"1234"\x0d\x0a
|
|
||||||
// Split: (2) DEVICE get version, +OK "value":"1234"
|
|
||||||
|
|
||||||
// Iterate the delimiters and fire an event for any matching delimiter
|
|
||||||
foreach (var delimiter in StringDelimiters)
|
|
||||||
{
|
|
||||||
var lines = Regex.Split(str, delimiter);
|
|
||||||
if (lines.Length == 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (int i = 0; i < lines.Length - 1; i++)
|
|
||||||
{
|
|
||||||
string strToSend = null;
|
|
||||||
if (IncludeDelimiter)
|
|
||||||
strToSend = lines[i] + delimiter;
|
|
||||||
else
|
|
||||||
strToSend = lines[i];
|
|
||||||
handler(this, new GenericCommMethodReceiveTextArgs(strToSend, delimiter));
|
|
||||||
}
|
|
||||||
ReceiveBuffer = new StringBuilder(lines[lines.Length - 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deconstructor. Disconnects from port TextReceived events.
|
|
||||||
/// </summary>
|
|
||||||
~CommunicationGather()
|
|
||||||
{
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,182 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Controls the ability to disable/enable debugging of TX/RX data sent to/from a device with a built in timer to disable
|
|
||||||
/// </summary>
|
|
||||||
public class CommunicationStreamDebugging
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Device Key that this instance configures
|
|
||||||
/// </summary>
|
|
||||||
public string ParentDeviceKey { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Timer to disable automatically if not manually disabled
|
|
||||||
/// </summary>
|
|
||||||
private CTimer DebugExpiryPeriod;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the DebugSetting
|
|
||||||
/// </summary>
|
|
||||||
public eStreamDebuggingSetting DebugSetting { get; private set; }
|
|
||||||
|
|
||||||
private uint _DebugTimeoutInMs;
|
|
||||||
private const uint _DefaultDebugTimeoutMin = 30;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Timeout in Minutes
|
|
||||||
/// </summary>
|
|
||||||
public uint DebugTimeoutMinutes
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _DebugTimeoutInMs/60000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the RxStreamDebuggingIsEnabled
|
|
||||||
/// </summary>
|
|
||||||
public bool RxStreamDebuggingIsEnabled{ get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates that transmit stream debugging is enabled
|
|
||||||
/// </summary>
|
|
||||||
public bool TxStreamDebuggingIsEnabled { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parentDeviceKey"></param>
|
|
||||||
public CommunicationStreamDebugging(string parentDeviceKey)
|
|
||||||
{
|
|
||||||
ParentDeviceKey = parentDeviceKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the debugging setting and if not setting to off, assumes the default of 30 mintues
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="setting"></param>
|
|
||||||
/// <summary>
|
|
||||||
/// SetDebuggingWithDefaultTimeout method
|
|
||||||
/// </summary>
|
|
||||||
public void SetDebuggingWithDefaultTimeout(eStreamDebuggingSetting setting)
|
|
||||||
{
|
|
||||||
if (setting == eStreamDebuggingSetting.Off)
|
|
||||||
{
|
|
||||||
DisableDebugging();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetDebuggingWithSpecificTimeout(setting, _DefaultDebugTimeoutMin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the debugging setting for the specified number of minutes
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="setting"></param>
|
|
||||||
/// <param name="minutes"></param>
|
|
||||||
/// <summary>
|
|
||||||
/// SetDebuggingWithSpecificTimeout method
|
|
||||||
/// </summary>
|
|
||||||
public void SetDebuggingWithSpecificTimeout(eStreamDebuggingSetting setting, uint minutes)
|
|
||||||
{
|
|
||||||
if (setting == eStreamDebuggingSetting.Off)
|
|
||||||
{
|
|
||||||
DisableDebugging();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_DebugTimeoutInMs = minutes * 60000;
|
|
||||||
|
|
||||||
StopDebugTimer();
|
|
||||||
|
|
||||||
DebugExpiryPeriod = new CTimer((o) => DisableDebugging(), _DebugTimeoutInMs);
|
|
||||||
|
|
||||||
if ((setting & eStreamDebuggingSetting.Rx) == eStreamDebuggingSetting.Rx)
|
|
||||||
RxStreamDebuggingIsEnabled = true;
|
|
||||||
|
|
||||||
if ((setting & eStreamDebuggingSetting.Tx) == eStreamDebuggingSetting.Tx)
|
|
||||||
TxStreamDebuggingIsEnabled = true;
|
|
||||||
|
|
||||||
Debug.SetDeviceDebugSettings(ParentDeviceKey, setting);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disabled debugging
|
|
||||||
/// </summary>
|
|
||||||
private void DisableDebugging()
|
|
||||||
{
|
|
||||||
StopDebugTimer();
|
|
||||||
|
|
||||||
Debug.SetDeviceDebugSettings(ParentDeviceKey, eStreamDebuggingSetting.Off);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void StopDebugTimer()
|
|
||||||
{
|
|
||||||
RxStreamDebuggingIsEnabled = false;
|
|
||||||
TxStreamDebuggingIsEnabled = false;
|
|
||||||
|
|
||||||
if (DebugExpiryPeriod == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugExpiryPeriod.Stop();
|
|
||||||
DebugExpiryPeriod.Dispose();
|
|
||||||
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,92 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Converters;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a ControlPropertiesConfig
|
|
||||||
/// </summary>
|
|
||||||
public class ControlPropertiesConfig
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The method of control
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("method")]
|
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
|
||||||
public eControlMethod Method { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The key of the device that contains the control port
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("controlPortDevKey", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public string ControlPortDevKey { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The number of the control port on the device specified by ControlPortDevKey
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("controlPortNumber", NullValueHandling = NullValueHandling.Ignore)] // In case "null" is present in config on this value
|
|
||||||
public uint? ControlPortNumber { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The name of the control port on the device specified by ControlPortDevKey
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("controlPortName", NullValueHandling = NullValueHandling.Ignore)] // In case "null" is present in config on this value
|
|
||||||
public string ControlPortName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Properties for ethernet based communications
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("tcpSshProperties", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public TcpSshPropertiesConfig TcpSshProperties { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The filename and path for the IR file
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("irFile", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public string IrFile { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The IpId of a Crestron device
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("ipId", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public string IpId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Readonly uint representation of the IpId
|
|
||||||
/// </summary>
|
|
||||||
[JsonIgnore]
|
|
||||||
public uint IpIdInt { get { return Convert.ToUInt32(IpId, 16); } }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Char indicating end of line
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("endOfLineChar", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public char EndOfLineChar { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defaults to Environment.NewLine;
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("endOfLineString", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public string EndOfLineString { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("deviceReadyResponsePattern", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public string DeviceReadyResponsePattern { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Used when communcating to programs running in VC-4
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("roomId", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public string RoomId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor
|
|
||||||
/// </summary>
|
|
||||||
public ControlPropertiesConfig()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,247 +0,0 @@
|
|||||||
/*PepperDash Technology Corp.
|
|
||||||
Copyright: 2017
|
|
||||||
------------------------------------
|
|
||||||
***Notice of Ownership and Copyright***
|
|
||||||
The material in which this notice appears is the property of PepperDash Technology Corporation,
|
|
||||||
which claims copyright under the laws of the United States of America in the entire body of material
|
|
||||||
and in all parts thereof, regardless of the use to which it is being put. Any use, in whole or in part,
|
|
||||||
of this material by another party without the express written permission of PepperDash Technology Corporation is prohibited.
|
|
||||||
PepperDash Technology Corporation reserves all rights under applicable laws.
|
|
||||||
------------------------------------ */
|
|
||||||
using System;
|
|
||||||
using Crestron.SimplSharp.CrestronSockets;
|
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Delegate for notifying of socket status changes
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="client"></param>
|
|
||||||
public delegate void GenericSocketStatusChangeEventDelegate(ISocketStatus client);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// EventArgs class for socket status changes
|
|
||||||
/// </summary>
|
|
||||||
public class GenericSocketStatusChageEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the Client
|
|
||||||
/// </summary>
|
|
||||||
public ISocketStatus Client { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="client"></param>
|
|
||||||
public GenericSocketStatusChageEventArgs(ISocketStatus client)
|
|
||||||
{
|
|
||||||
Client = client;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// S+ Constructor
|
|
||||||
/// </summary>
|
|
||||||
public GenericSocketStatusChageEventArgs() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delegate for notifying of TCP Server state changes
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="state"></param>
|
|
||||||
public delegate void GenericTcpServerStateChangedEventDelegate(ServerState state);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// EventArgs class for TCP Server state changes
|
|
||||||
/// </summary>
|
|
||||||
public class GenericTcpServerStateChangedEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the State
|
|
||||||
/// </summary>
|
|
||||||
public ServerState State { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="state"></param>
|
|
||||||
public GenericTcpServerStateChangedEventArgs(ServerState state)
|
|
||||||
{
|
|
||||||
State = state;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// S+ Constructor
|
|
||||||
/// </summary>
|
|
||||||
public GenericTcpServerStateChangedEventArgs() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delegate for TCP Server socket status changes
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="socket"></param>
|
|
||||||
/// <param name="clientIndex"></param>
|
|
||||||
/// <param name="clientStatus"></param>
|
|
||||||
public delegate void GenericTcpServerSocketStatusChangeEventDelegate(object socket, uint clientIndex, SocketStatus clientStatus);
|
|
||||||
/// <summary>
|
|
||||||
/// EventArgs for TCP server socket status changes
|
|
||||||
/// </summary>
|
|
||||||
public class GenericTcpServerSocketStatusChangeEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public object Socket { get; private set; }
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public uint ReceivedFromClientIndex { get; private set; }
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public SocketStatus ClientStatus { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="socket"></param>
|
|
||||||
/// <param name="clientStatus"></param>
|
|
||||||
public GenericTcpServerSocketStatusChangeEventArgs(object socket, SocketStatus clientStatus)
|
|
||||||
{
|
|
||||||
Socket = socket;
|
|
||||||
ClientStatus = clientStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="socket"></param>
|
|
||||||
/// <param name="clientIndex"></param>
|
|
||||||
/// <param name="clientStatus"></param>
|
|
||||||
public GenericTcpServerSocketStatusChangeEventArgs(object socket, uint clientIndex, SocketStatus clientStatus)
|
|
||||||
{
|
|
||||||
Socket = socket;
|
|
||||||
ReceivedFromClientIndex = clientIndex;
|
|
||||||
ClientStatus = clientStatus;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// S+ Constructor
|
|
||||||
/// </summary>
|
|
||||||
public GenericTcpServerSocketStatusChangeEventArgs() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// EventArgs for TCP server com method receive text
|
|
||||||
/// </summary>
|
|
||||||
public class GenericTcpServerCommMethodReceiveTextArgs : EventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public uint ReceivedFromClientIndex { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public ushort ReceivedFromClientIndexShort
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return (ushort)ReceivedFromClientIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the Text
|
|
||||||
/// </summary>
|
|
||||||
public string Text { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
public GenericTcpServerCommMethodReceiveTextArgs(string text)
|
|
||||||
{
|
|
||||||
Text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
/// <param name="clientIndex"></param>
|
|
||||||
public GenericTcpServerCommMethodReceiveTextArgs(string text, uint clientIndex)
|
|
||||||
{
|
|
||||||
Text = text;
|
|
||||||
ReceivedFromClientIndex = clientIndex;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// S+ Constructor
|
|
||||||
/// </summary>
|
|
||||||
public GenericTcpServerCommMethodReceiveTextArgs() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// EventArgs for TCP server client ready for communication
|
|
||||||
/// </summary>
|
|
||||||
public class GenericTcpServerClientReadyForcommunicationsEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public bool IsReady;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="isReady"></param>
|
|
||||||
public GenericTcpServerClientReadyForcommunicationsEventArgs(bool isReady)
|
|
||||||
{
|
|
||||||
IsReady = isReady;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// S+ Constructor
|
|
||||||
/// </summary>
|
|
||||||
public GenericTcpServerClientReadyForcommunicationsEventArgs() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// EventArgs for UDP connected
|
|
||||||
/// </summary>
|
|
||||||
public class GenericUdpConnectedEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public ushort UConnected;
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public bool Connected;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor
|
|
||||||
/// </summary>
|
|
||||||
public GenericUdpConnectedEventArgs() { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="uconnected"></param>
|
|
||||||
public GenericUdpConnectedEventArgs(ushort uconnected)
|
|
||||||
{
|
|
||||||
UConnected = uconnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="connected"></param>
|
|
||||||
public GenericUdpConnectedEventArgs(bool connected)
|
|
||||||
{
|
|
||||||
Connected = connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Describes a device that can automatically attempt to reconnect
|
|
||||||
/// </summary>
|
|
||||||
public interface IAutoReconnect
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Enable automatic recconnect
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("autoReconnect")]
|
|
||||||
bool AutoReconnect { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Interval in ms to attempt automatic recconnections
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("autoReconnectIntervalMs")]
|
|
||||||
int AutoReconnectIntervalMs { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Defines the contract for IBasicCommunication
|
|
||||||
/// </summary>
|
|
||||||
public interface IBasicCommunication : ICommunicationReceiver
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Send text to the device
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
void SendText(string text);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Send bytes to the device
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes"></param>
|
|
||||||
void SendBytes(byte[] bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a device that implements IBasicCommunication and IStreamDebugging
|
|
||||||
/// </summary>
|
|
||||||
public interface IBasicCommunicationWithStreamDebugging : IBasicCommunication, IStreamDebugging
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using Crestron.SimplSharpPro;
|
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public interface IComPortsDevice
|
|
||||||
{
|
|
||||||
IComPorts Device { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An incoming communication stream
|
|
||||||
/// </summary>
|
|
||||||
public interface ICommunicationReceiver : IKeyed
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Notifies of bytes received
|
|
||||||
/// </summary>
|
|
||||||
event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
|
||||||
/// <summary>
|
|
||||||
/// Notifies of text received
|
|
||||||
/// </summary>
|
|
||||||
event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates connection status
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("isConnected")]
|
|
||||||
bool IsConnected { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Connect to the device
|
|
||||||
/// </summary>
|
|
||||||
void Connect();
|
|
||||||
/// <summary>
|
|
||||||
/// Disconnect from the device
|
|
||||||
/// </summary>
|
|
||||||
void Disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Crestron.SimplSharp.CrestronSockets;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// For IBasicCommunication classes that have SocketStatus. GenericSshClient,
|
|
||||||
/// GenericTcpIpClient
|
|
||||||
/// </summary>
|
|
||||||
public interface ISocketStatus : IBasicCommunication
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Notifies of socket status changes
|
|
||||||
/// </summary>
|
|
||||||
event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current socket status of the client
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("clientStatus")]
|
|
||||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
|
||||||
SocketStatus ClientStatus { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Describes a device that implements ISocketStatus and IStreamDebugging
|
|
||||||
/// </summary>
|
|
||||||
public interface ISocketStatusWithStreamDebugging : ISocketStatus, IStreamDebugging
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a device with stream debugging capablities
|
|
||||||
/// </summary>
|
|
||||||
public interface IStreamDebugging
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Object to enable stream debugging
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("streamDebugging")]
|
|
||||||
CommunicationStreamDebugging StreamDebugging { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a TcpClientConfigObject
|
|
||||||
/// </summary>
|
|
||||||
public class TcpClientConfigObject
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// TcpSsh Properties
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("control")]
|
|
||||||
public ControlPropertiesConfig Control { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Bool value for secure. Currently not implemented in TCP sockets as they are not dynamic
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("secure")]
|
|
||||||
public bool Secure { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Require a shared key that both server and client negotiate. If negotiation fails server disconnects the client
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("sharedKeyRequired")]
|
|
||||||
public bool SharedKeyRequired { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The shared key that must match on the server and client
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("sharedKey")]
|
|
||||||
public string SharedKey { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Require a heartbeat on the client/server connection that will cause the server/client to disconnect if the heartbeat is not received.
|
|
||||||
/// heartbeats do not raise received events.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("heartbeatRequired")]
|
|
||||||
public bool HeartbeatRequired { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The interval in seconds for the heartbeat from the client. If not received client is disconnected
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("heartbeatRequiredIntervalInSeconds")]
|
|
||||||
public ushort HeartbeatRequiredIntervalInSeconds { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// HeartbeatString that will be checked against the message received. defaults to heartbeat if no string is provided.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("heartbeatStringToMatch")]
|
|
||||||
public string HeartbeatStringToMatch { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Receive Queue size must be greater than 20 or defaults to 20
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("receiveQueueSize")]
|
|
||||||
public int ReceiveQueueSize { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tcp Server Config object with properties for a tcp server with shared key and heartbeat capabilities
|
|
||||||
/// </summary>
|
|
||||||
public class TcpServerConfigObject
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Uique key
|
|
||||||
/// </summary>
|
|
||||||
public string Key { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Max Clients that the server will allow to connect.
|
|
||||||
/// </summary>
|
|
||||||
public ushort MaxClients { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Bool value for secure. Currently not implemented in TCP sockets as they are not dynamic
|
|
||||||
/// </summary>
|
|
||||||
public bool Secure { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Port for the server to listen on
|
|
||||||
/// </summary>
|
|
||||||
public int Port { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Require a shared key that both server and client negotiate. If negotiation fails server disconnects the client
|
|
||||||
/// </summary>
|
|
||||||
public bool SharedKeyRequired { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// The shared key that must match on the server and client
|
|
||||||
/// </summary>
|
|
||||||
public string SharedKey { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Require a heartbeat on the client/server connection that will cause the server/client to disconnect if the heartbeat is not received.
|
|
||||||
/// heartbeats do not raise received events.
|
|
||||||
/// </summary>
|
|
||||||
public bool HeartbeatRequired { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// The interval in seconds for the heartbeat from the client. If not received client is disconnected
|
|
||||||
/// </summary>
|
|
||||||
public ushort HeartbeatRequiredIntervalInSeconds { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// HeartbeatString that will be checked against the message received. defaults to heartbeat if no string is provided.
|
|
||||||
/// </summary>
|
|
||||||
public string HeartbeatStringToMatch { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Client buffer size. See Crestron help. defaults to 2000 if not greater than 2000
|
|
||||||
/// </summary>
|
|
||||||
public int BufferSize { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Receive Queue size must be greater than 20 or defaults to 20
|
|
||||||
/// </summary>
|
|
||||||
public int ReceiveQueueSize { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a TcpSshPropertiesConfig
|
|
||||||
/// </summary>
|
|
||||||
public class TcpSshPropertiesConfig
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Address to connect to
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
public string Address { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Port to connect to
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty(Required = Required.Always)]
|
|
||||||
public int Port { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Username credential
|
|
||||||
/// </summary>
|
|
||||||
public string Username { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the Password
|
|
||||||
/// </summary>
|
|
||||||
public string Password { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defaults to 32768
|
|
||||||
/// </summary>
|
|
||||||
public int BufferSize { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the AutoReconnect
|
|
||||||
/// </summary>
|
|
||||||
public bool AutoReconnect { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the AutoReconnectIntervalMs
|
|
||||||
/// </summary>
|
|
||||||
public int AutoReconnectIntervalMs { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default constructor
|
|
||||||
/// </summary>
|
|
||||||
public TcpSshPropertiesConfig()
|
|
||||||
{
|
|
||||||
BufferSize = 32768;
|
|
||||||
AutoReconnect = true;
|
|
||||||
AutoReconnectIntervalMs = 5000;
|
|
||||||
Username = "";
|
|
||||||
Password = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
namespace PepperDash.Essentials.Core.Communications
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Crestron Control Methods for a comm object
|
|
||||||
/// </summary>
|
|
||||||
public enum eControlMethod
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
None = 0,
|
|
||||||
/// <summary>
|
|
||||||
/// RS232/422/485
|
|
||||||
/// </summary>
|
|
||||||
Com,
|
|
||||||
/// <summary>
|
|
||||||
/// Crestron IpId (most Crestron ethernet devices)
|
|
||||||
/// </summary>
|
|
||||||
IpId,
|
|
||||||
/// <summary>
|
|
||||||
/// Crestron IpIdTcp (HD-MD series, etc.)
|
|
||||||
/// </summary>
|
|
||||||
IpidTcp,
|
|
||||||
/// <summary>
|
|
||||||
/// Crestron IR control
|
|
||||||
/// </summary>
|
|
||||||
IR,
|
|
||||||
/// <summary>
|
|
||||||
/// SSH client
|
|
||||||
/// </summary>
|
|
||||||
Ssh,
|
|
||||||
/// <summary>
|
|
||||||
/// TCP/IP client
|
|
||||||
/// </summary>
|
|
||||||
Tcpip,
|
|
||||||
/// <summary>
|
|
||||||
/// Telnet
|
|
||||||
/// </summary>
|
|
||||||
Telnet,
|
|
||||||
/// <summary>
|
|
||||||
/// Crestnet device
|
|
||||||
/// </summary>
|
|
||||||
Cresnet,
|
|
||||||
/// <summary>
|
|
||||||
/// CEC Control, via a DM HDMI port
|
|
||||||
/// </summary>
|
|
||||||
Cec,
|
|
||||||
/// <summary>
|
|
||||||
/// UDP Server
|
|
||||||
/// </summary>
|
|
||||||
Udp,
|
|
||||||
/// <summary>
|
|
||||||
/// HTTP client
|
|
||||||
/// </summary>
|
|
||||||
Http,
|
|
||||||
/// <summary>
|
|
||||||
/// HTTPS client
|
|
||||||
/// </summary>
|
|
||||||
Https,
|
|
||||||
/// <summary>
|
|
||||||
/// Websocket client
|
|
||||||
/// </summary>
|
|
||||||
Ws,
|
|
||||||
/// <summary>
|
|
||||||
/// Secure Websocket client
|
|
||||||
/// </summary>
|
|
||||||
Wss,
|
|
||||||
/// <summary>
|
|
||||||
/// Secure TCP/IP
|
|
||||||
/// </summary>
|
|
||||||
SecureTcpIp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
using Newtonsoft.Json;
|
using Crestron.SimplSharpPro;
|
||||||
using PepperDash.Essentials.Core.Devices;
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Config
|
namespace PepperDash.Essentials.Core.Config
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the base properties for a streaming device.
|
||||||
|
/// </summary>
|
||||||
|
public class BaseStreamingDeviceProperties
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The multicast video address for the streaming device.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("multicastVideoAddress", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public string MulticastVideoAddress { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The multicast audio address for the streaming device.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("multicastAudioAddress", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public string MulticastAudioAddress { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The URL for the streaming device's media stream.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("streamUrl", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public string StreamUrl { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using PepperDash.Essentials.Core.Devices;
|
using PepperDash.Essentials.Core.Devices;
|
||||||
using PepperDash.Essentials.Core.Routing;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Config
|
namespace PepperDash.Essentials.Core.Config
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,15 @@
|
|||||||
namespace PepperDash.Essentials.Core.Config
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a ConfigPropertiesHelpers
|
/// Represents a ConfigPropertiesHelpers
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Config
|
namespace PepperDash.Essentials.Core.Config
|
||||||
{
|
{
|
||||||
@@ -12,41 +18,41 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DeviceConfig
|
public class DeviceConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("key")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Key
|
/// Gets or sets the Key
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("key")]
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
|
|
||||||
[JsonProperty("uid")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Uid
|
/// Gets or sets the Uid
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("uid")]
|
||||||
public int Uid { get; set; }
|
public int Uid { get; set; }
|
||||||
|
|
||||||
[JsonProperty("name")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Name
|
/// Gets or sets the Name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("name")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
[JsonProperty("group")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Group
|
/// Gets or sets the Group
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("group")]
|
||||||
public string Group { get; set; }
|
public string Group { get; set; }
|
||||||
|
|
||||||
[JsonProperty("type")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Type
|
/// Gets or sets the Type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("type")]
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
|
|
||||||
[JsonProperty("properties")]
|
|
||||||
[JsonConverter(typeof(DevicePropertiesConverter))]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Properties
|
/// Gets or sets the Properties
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("properties")]
|
||||||
|
[JsonConverter(typeof(DevicePropertiesConverter))]
|
||||||
public JToken Properties { get; set; }
|
public JToken Properties { get; set; }
|
||||||
|
|
||||||
public DeviceConfig(DeviceConfig dc)
|
public DeviceConfig(DeviceConfig dc)
|
||||||
@@ -62,7 +68,7 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
//Properties = JToken.FromObject(dc.Properties);
|
//Properties = JToken.FromObject(dc.Properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceConfig() {}
|
public DeviceConfig() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user