mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 20:54:55 +00:00
Compare commits
58 Commits
copilot/fi
...
v2.17.0-fe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9de94bd65f | ||
|
|
ff46fb8f29 | ||
|
|
d9243def30 | ||
|
|
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 | ||
|
|
4f0d464ba4 | ||
|
|
0107422507 | ||
|
|
1a366790e7 | ||
|
|
bb4b2f88b6 | ||
|
|
a41aba1904 | ||
|
|
b47f1d6b77 | ||
|
|
fda4a5a816 | ||
|
|
9f70e3c721 | ||
|
|
ec6aeb17f6 | ||
|
|
91dc655103 | ||
|
|
bf31fb10eb | ||
|
|
5e21bad596 | ||
|
|
2368f0c8cc | ||
|
|
be58a0bc29 | ||
|
|
8406f69e0d | ||
|
|
116d83394a | ||
|
|
9b8e452eb4 | ||
|
|
c9d86bd5dd | ||
|
|
b2b257020f | ||
|
|
6f58e18d14 | ||
|
|
60fc0298ec |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -395,3 +395,4 @@ essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/Pepp
|
|||||||
_site/
|
_site/
|
||||||
api/
|
api/
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
|
/._PepperDash.Essentials.4Series.sln
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>2.12.1-local</Version>
|
<Version>2.15.1-local</Version>
|
||||||
<InformationalVersion>$(Version)</InformationalVersion>
|
<InformationalVersion>$(Version)</InformationalVersion>
|
||||||
<Authors>PepperDash Technology</Authors>
|
<Authors>PepperDash Technology</Authors>
|
||||||
<Company>PepperDash Technology</Company>
|
<Company>PepperDash Technology</Company>
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ namespace PepperDash.Core
|
|||||||
/// <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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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}", propPath, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,12 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Crestron.SimplSharp;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
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.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
@@ -355,22 +353,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; }
|
||||||
|
|
||||||
|
|
||||||
@@ -379,22 +377,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; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,22 +401,22 @@ 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; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Crestron.SimplSharp;
|
|
||||||
using Crestron.SimplSharpPro;
|
using Crestron.SimplSharpPro;
|
||||||
using Crestron.SimplSharpPro.DM;
|
using Crestron.SimplSharpPro.DM;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
@@ -38,9 +36,9 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// Returns a comm method of either com port, TCP, SSH, and puts this into the DeviceManager
|
/// Returns a comm method of either com port, TCP, SSH, and puts this into the DeviceManager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="deviceConfig">The Device config object</param>
|
/// <param name="deviceConfig">The Device config object</param>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CreateCommForDevice method
|
/// CreateCommForDevice method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IBasicCommunication CreateCommForDevice(DeviceConfig deviceConfig)
|
public static IBasicCommunication CreateCommForDevice(DeviceConfig deviceConfig)
|
||||||
{
|
{
|
||||||
EssentialsControlPropertiesConfig controlConfig = GetControlPropertiesConfig(deviceConfig);
|
EssentialsControlPropertiesConfig controlConfig = GetControlPropertiesConfig(deviceConfig);
|
||||||
@@ -56,35 +54,38 @@ namespace PepperDash.Essentials.Core
|
|||||||
case eControlMethod.Com:
|
case eControlMethod.Com:
|
||||||
comm = new ComPortController(deviceConfig.Key + "-com", GetComPort, controlConfig.ComParams.Value, controlConfig);
|
comm = new ComPortController(deviceConfig.Key + "-com", GetComPort, controlConfig.ComParams.Value, controlConfig);
|
||||||
break;
|
break;
|
||||||
case eControlMethod.Cec:
|
case eControlMethod.ComBridge:
|
||||||
comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort, controlConfig);
|
comm = new CommBridge(deviceConfig.Key + "-simpl", deviceConfig.Name + " Simpl");
|
||||||
break;
|
break;
|
||||||
|
case eControlMethod.Cec:
|
||||||
|
comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort, controlConfig);
|
||||||
|
break;
|
||||||
case eControlMethod.IR:
|
case eControlMethod.IR:
|
||||||
break;
|
break;
|
||||||
case eControlMethod.Ssh:
|
case eControlMethod.Ssh:
|
||||||
{
|
{
|
||||||
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password);
|
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password);
|
||||||
ssh.AutoReconnect = c.AutoReconnect;
|
ssh.AutoReconnect = c.AutoReconnect;
|
||||||
if(ssh.AutoReconnect)
|
if (ssh.AutoReconnect)
|
||||||
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||||
comm = ssh;
|
comm = ssh;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eControlMethod.Tcpip:
|
case eControlMethod.Tcpip:
|
||||||
{
|
{
|
||||||
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize);
|
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize);
|
||||||
tcp.AutoReconnect = c.AutoReconnect;
|
tcp.AutoReconnect = c.AutoReconnect;
|
||||||
if (tcp.AutoReconnect)
|
if (tcp.AutoReconnect)
|
||||||
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||||
comm = tcp;
|
comm = tcp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eControlMethod.Udp:
|
case eControlMethod.Udp:
|
||||||
{
|
{
|
||||||
var udp = new GenericUdpServer(deviceConfig.Key + "-udp", c.Address, c.Port, c.BufferSize);
|
var udp = new GenericUdpServer(deviceConfig.Key + "-udp", c.Address, c.Port, c.BufferSize);
|
||||||
comm = udp;
|
comm = udp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eControlMethod.Telnet:
|
case eControlMethod.Telnet:
|
||||||
break;
|
break;
|
||||||
case eControlMethod.SecureTcpIp:
|
case eControlMethod.SecureTcpIp:
|
||||||
@@ -107,15 +108,14 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
// put it in the device manager if it's the right flavor
|
// put it in the device manager if it's the right flavor
|
||||||
var comDev = comm as Device;
|
if (comm is Device comDev)
|
||||||
if (comDev != null)
|
|
||||||
DeviceManager.AddDevice(comDev);
|
DeviceManager.AddDevice(comDev);
|
||||||
return comm;
|
return comm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GetComPort method
|
/// GetComPort method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
|
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
|
||||||
{
|
{
|
||||||
var comPar = config.ComParams;
|
var comPar = config.ComParams;
|
||||||
@@ -126,74 +126,74 @@ namespace PepperDash.Essentials.Core
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets an ICec port from a RoutingInput or RoutingOutput on a device
|
/// Gets an ICec port from a RoutingInput or RoutingOutput on a device
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="config"></param>
|
/// <param name="config"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GetCecPort method
|
/// GetCecPort method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static ICec GetCecPort(ControlPropertiesConfig config)
|
public static ICec GetCecPort(ControlPropertiesConfig config)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey);
|
var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey);
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: device '{0}' {1}", config.ControlPortDevKey, dev == null
|
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: device '{0}' {1}", config.ControlPortDevKey, dev == null
|
||||||
? "is not valid, failed to get cec port"
|
? "is not valid, failed to get cec port"
|
||||||
: "found in device manager, attempting to get cec port");
|
: "found in device manager, attempting to get cec port");
|
||||||
|
|
||||||
if (dev == null)
|
if (dev == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(config.ControlPortName))
|
if (String.IsNullOrEmpty(config.ControlPortName))
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey);
|
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var inputsOutputs = dev as IRoutingInputsOutputs;
|
var inputsOutputs = dev as IRoutingInputsOutputs;
|
||||||
if (inputsOutputs == null)
|
if (inputsOutputs == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: Device '{0}' does not support IRoutingInputsOutputs, failed to get CEC port called '{1}'",
|
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: Device '{0}' does not support IRoutingInputsOutputs, failed to get CEC port called '{1}'",
|
||||||
config.ControlPortDevKey, config.ControlPortName);
|
config.ControlPortDevKey, config.ControlPortName);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var inputPort = inputsOutputs.InputPorts[config.ControlPortName];
|
var inputPort = inputsOutputs.InputPorts[config.ControlPortName];
|
||||||
if (inputPort != null && inputPort.Port is ICec)
|
if (inputPort != null && inputPort.Port is ICec)
|
||||||
return inputPort.Port as ICec;
|
return inputPort.Port as ICec;
|
||||||
|
|
||||||
|
|
||||||
var outputPort = inputsOutputs.OutputPorts[config.ControlPortName];
|
var outputPort = inputsOutputs.OutputPorts[config.ControlPortName];
|
||||||
if (outputPort != null && outputPort.Port is ICec)
|
if (outputPort != null && outputPort.Port is ICec)
|
||||||
return outputPort.Port as ICec;
|
return outputPort.Port as ICec;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "GetCecPort Exception Message: {0}", ex.Message);
|
Debug.LogMessage(LogEventLevel.Debug, "GetCecPort Exception Message: {0}", ex.Message);
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "GetCecPort Exception StackTrace: {0}", ex.StackTrace);
|
Debug.LogMessage(LogEventLevel.Verbose, "GetCecPort Exception StackTrace: {0}", ex.StackTrace);
|
||||||
if (ex.InnerException != null)
|
if (ex.InnerException != null)
|
||||||
Debug.LogMessage(LogEventLevel.Information, "GetCecPort Exception InnerException: {0}", ex.InnerException);
|
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}'",
|
Debug.LogMessage(LogEventLevel.Information, "GetCecPort: Device '{0}' does not have a CEC port called '{1}'",
|
||||||
config.ControlPortDevKey, config.ControlPortName);
|
config.ControlPortDevKey, config.ControlPortName);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper to grab the IComPorts device for this PortDeviceKey. Key "controlSystem" will
|
/// Helper to grab the IComPorts device for this PortDeviceKey. Key "controlSystem" will
|
||||||
/// return the ControlSystem object from the Global class.
|
/// return the ControlSystem object from the Global class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>IComPorts device or null if the device is not found or does not implement IComPorts</returns>
|
/// <returns>IComPorts device or null if the device is not found or does not implement IComPorts</returns>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GetIComPortsDeviceFromManagedDevice method
|
/// GetIComPortsDeviceFromManagedDevice method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IComPorts GetIComPortsDeviceFromManagedDevice(string ComPortDevKey)
|
public static IComPorts GetIComPortsDeviceFromManagedDevice(string ComPortDevKey)
|
||||||
{
|
{
|
||||||
if ((ComPortDevKey.Equals("controlSystem", System.StringComparison.OrdinalIgnoreCase)
|
if ((ComPortDevKey.Equals("controlSystem", System.StringComparison.OrdinalIgnoreCase)
|
||||||
@@ -210,81 +210,81 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a EssentialsControlPropertiesConfig
|
/// Represents a EssentialsControlPropertiesConfig
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsControlPropertiesConfig :
|
public class EssentialsControlPropertiesConfig :
|
||||||
ControlPropertiesConfig
|
ControlPropertiesConfig
|
||||||
{
|
{
|
||||||
|
|
||||||
[JsonProperty("comParams", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("comParams", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
[JsonConverter(typeof(ComSpecJsonConverter))]
|
[JsonConverter(typeof(ComSpecJsonConverter))]
|
||||||
public ComPort.ComPortSpec? ComParams { get; set; }
|
public ComPort.ComPortSpec? ComParams { get; set; }
|
||||||
|
|
||||||
[JsonProperty("cresnetId", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("cresnetId", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public string CresnetId { get; set; }
|
public string CresnetId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attempts to provide uint conversion of string CresnetId
|
/// Attempts to provide uint conversion of string CresnetId
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public uint CresnetIdInt
|
public uint CresnetIdInt
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Convert.ToUInt32(CresnetId, 16);
|
return Convert.ToUInt32(CresnetId, 16);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
throw new FormatException(string.Format("ERROR:Unable to convert Cresnet ID: {0} to hex. Error:\n{1}", CresnetId));
|
throw new FormatException(string.Format("ERROR:Unable to convert Cresnet ID: {0} to hex. Error:\n{1}", CresnetId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonProperty("infinetId", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("infinetId", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the InfinetId
|
/// Gets or sets the InfinetId
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string InfinetId { get; set; }
|
public string InfinetId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attepmts to provide uiont conversion of string InifinetId
|
/// Attepmts to provide uiont conversion of string InifinetId
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public uint InfinetIdInt
|
public uint InfinetIdInt
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Convert.ToUInt32(InfinetId, 16);
|
return Convert.ToUInt32(InfinetId, 16);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
throw new FormatException(string.Format("ERROR:Unable to conver Infinet ID: {0} to hex. Error:\n{1}", InfinetId));
|
throw new FormatException(string.Format("ERROR:Unable to conver Infinet ID: {0} to hex. Error:\n{1}", InfinetId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a IrControlSpec
|
/// Represents a IrControlSpec
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IrControlSpec
|
public class IrControlSpec
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the PortDeviceKey
|
/// Gets or sets the PortDeviceKey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PortDeviceKey { get; set; }
|
public string PortDeviceKey { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the PortNumber
|
/// Gets or sets the PortNumber
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint PortNumber { get; set; }
|
public uint PortNumber { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the File
|
/// Gets or sets the File
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string File { get; set; }
|
public string File { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,5 +19,11 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("multicastAudioAddress", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("multicastAudioAddress", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public string MulticastAudioAddress { get; set; }
|
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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,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)
|
||||||
@@ -68,7 +68,7 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
//Properties = JToken.FromObject(dc.Properties);
|
//Properties = JToken.FromObject(dc.Properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceConfig() {}
|
public DeviceConfig() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -127,19 +127,32 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var doubleObj = JObject.Parse(fs.ReadToEnd());
|
var parsedConfig = JObject.Parse(fs.ReadToEnd());
|
||||||
ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
|
|
||||||
|
|
||||||
// Extract SystemUrl and TemplateUrl into final config output
|
// Check if it's a v2 config (check for "version" node)
|
||||||
|
// this means it's already merged by the Portal API
|
||||||
|
// from the v2 config tool
|
||||||
|
var isV2Config = parsedConfig["versions"] != null;
|
||||||
|
|
||||||
if (doubleObj["system_url"] != null)
|
if (isV2Config)
|
||||||
{
|
{
|
||||||
ConfigObject.SystemUrl = doubleObj["system_url"].Value<string>();
|
Debug.LogMessage(LogEventLevel.Information, "Config file is a v2 format, no merge necessary.");
|
||||||
|
ConfigObject = parsedConfig.ToObject<EssentialsConfig>();
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "Successfully Loaded v2 Config");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doubleObj["template_url"] != null)
|
// Extract SystemUrl and TemplateUrl into final config output
|
||||||
|
ConfigObject = PortalConfigReader.MergeConfigs(parsedConfig).ToObject<EssentialsConfig>();
|
||||||
|
|
||||||
|
if (parsedConfig["system_url"] != null)
|
||||||
{
|
{
|
||||||
ConfigObject.TemplateUrl = doubleObj["template_url"].Value<string>();
|
ConfigObject.SystemUrl = parsedConfig["system_url"].Value<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsedConfig["template_url"] != null)
|
||||||
|
{
|
||||||
|
ConfigObject.TemplateUrl = parsedConfig["template_url"].Value<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,21 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsConfig : BasicConfig
|
public class EssentialsConfig : BasicConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("system_url")]
|
/// <summary>
|
||||||
|
/// Gets or sets the SystemUrl
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("system_url")]
|
||||||
public string SystemUrl { get; set; }
|
public string SystemUrl { get; set; }
|
||||||
|
|
||||||
[JsonProperty("template_url")]
|
/// <summary>
|
||||||
|
/// Gets or sets the TemplateUrl
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("template_url")]
|
||||||
public string TemplateUrl { get; set; }
|
public string TemplateUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the SystemUuid extracted from the SystemUrl
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("systemUuid")]
|
[JsonProperty("systemUuid")]
|
||||||
public string SystemUuid
|
public string SystemUuid
|
||||||
{
|
{
|
||||||
@@ -45,6 +53,9 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the TemplateUuid extracted from the TemplateUrl
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("templateUuid")]
|
[JsonProperty("templateUuid")]
|
||||||
public string TemplateUuid
|
public string TemplateUuid
|
||||||
{
|
{
|
||||||
@@ -67,13 +78,21 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonProperty("rooms")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Rooms
|
/// Gets or sets the Rooms
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("rooms")]
|
||||||
|
|
||||||
public List<DeviceConfig> Rooms { get; set; }
|
public List<DeviceConfig> Rooms { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Versions
|
||||||
|
/// </summary>
|
||||||
|
public VersionData Versions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="EssentialsConfig"/> class.
|
||||||
|
/// </summary>
|
||||||
public EssentialsConfig()
|
public EssentialsConfig()
|
||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
@@ -81,16 +100,63 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a SystemTemplateConfigs
|
/// Represents version data for Essentials and its packages
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SystemTemplateConfigs
|
public class VersionData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Essentials version
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("essentials")]
|
||||||
|
public NugetVersion Essentials { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the list of Packages
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("packages")]
|
||||||
|
public List<NugetVersion> Packages { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="VersionData"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public VersionData()
|
||||||
|
{
|
||||||
|
Packages = new List<NugetVersion>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a NugetVersion
|
||||||
|
/// </summary>
|
||||||
|
public class NugetVersion
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Version
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("version")]
|
||||||
|
public string Version { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the PackageId
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("packageId")]
|
||||||
|
public string PackageId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a SystemTemplateConfigs
|
||||||
|
/// </summary>
|
||||||
|
public class SystemTemplateConfigs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the System
|
/// Gets or sets the System
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EssentialsConfig System { get; set; }
|
public EssentialsConfig System { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Template
|
||||||
|
/// </summary>
|
||||||
public EssentialsConfig Template { get; set; }
|
public EssentialsConfig Template { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using Crestron.SimplSharpPro.DM.Streaming;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Crestron.SimplSharpPro.DM.Streaming;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
@@ -11,7 +12,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// subscribers when the port information is updated. Implementations of this interface should ensure that the <see
|
/// subscribers when the port information is updated. Implementations of this interface should ensure that the <see
|
||||||
/// cref="PortInformationChanged"/> event is raised whenever the <see cref="NetworkPorts"/> collection
|
/// cref="PortInformationChanged"/> event is raised whenever the <see cref="NetworkPorts"/> collection
|
||||||
/// changes.</remarks>
|
/// changes.</remarks>
|
||||||
public interface INvxNetworkPortInformation
|
public interface INvxNetworkPortInformation : IKeyed
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the port information changes.
|
/// Occurs when the port information changes.
|
||||||
|
|||||||
@@ -202,14 +202,15 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
private static void ListDevices(string s)
|
private static void ListDevices(string s)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "{0} Devices registered with Device Manager:", Devices.Count);
|
CrestronConsole.ConsoleCommandResponse($"{Devices.Count} Devices registered with Device Manager:\r\n");
|
||||||
|
|
||||||
var sorted = Devices.Values.ToList();
|
var sorted = Devices.Values.ToList();
|
||||||
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
|
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
|
||||||
|
|
||||||
foreach (var d in sorted)
|
foreach (var d in sorted)
|
||||||
{
|
{
|
||||||
var name = d is IKeyName ? (d as IKeyName).Name : "---";
|
var name = d is IKeyName ? (d as IKeyName).Name : "---";
|
||||||
Debug.LogMessage(LogEventLevel.Information, " [{0}] {1}", d.Key, name);
|
CrestronConsole.ConsoleCommandResponse($" [{d.Key}] {name}\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,28 +219,17 @@ namespace PepperDash.Essentials.Core
|
|||||||
var dev = GetDeviceForKey(devKey);
|
var dev = GetDeviceForKey(devKey);
|
||||||
if (dev == null)
|
if (dev == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Device '{0}' not found", devKey);
|
CrestronConsole.ConsoleCommandResponse($"Device '{devKey}' not found\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(dev is IHasFeedback statusDev))
|
if (!(dev is IHasFeedback statusDev))
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Device '{0}' does not have visible feedbacks", devKey);
|
CrestronConsole.ConsoleCommandResponse($"Device '{devKey}' does not have visible feedbacks\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
statusDev.DumpFeedbacksToConsole(true);
|
statusDev.DumpFeedbacksToConsole(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static void ListDeviceCommands(string devKey)
|
|
||||||
//{
|
|
||||||
// var dev = GetDeviceForKey(devKey);
|
|
||||||
// if (dev == null)
|
|
||||||
// {
|
|
||||||
// Debug.LogMessage(LogEventLevel.Information, "Device '{0}' not found", devKey);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// Debug.LogMessage(LogEventLevel.Information, "This needs to be reworked. Stay tuned.", devKey);
|
|
||||||
//}
|
|
||||||
|
|
||||||
private static void ListDeviceCommStatuses(string input)
|
private static void ListDeviceCommStatuses(string input)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -249,12 +239,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//static void DoDeviceCommand(string command)
|
|
||||||
//{
|
|
||||||
// Debug.LogMessage(LogEventLevel.Information, "Not yet implemented. Stay tuned");
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// AddDevice method
|
/// AddDevice method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -3,16 +3,29 @@ using PepperDash.Essentials.Core.Bridges;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
public abstract class EssentialsBridgeableDevice:EssentialsDevice, IBridgeAdvanced
|
/// <summary>
|
||||||
|
/// Base class for devices that can be bridged to an EISC API.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class EssentialsBridgeableDevice : EssentialsDevice, IBridgeAdvanced
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="EssentialsBridgeableDevice"/> class with the specified key.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The unique key for the device.</param>
|
||||||
protected EssentialsBridgeableDevice(string key) : base(key)
|
protected EssentialsBridgeableDevice(string key) : base(key)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="EssentialsBridgeableDevice"/> class with the specified key and name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The unique key for the device.</param>
|
||||||
|
/// <param name="name">The display name for the device.</param>
|
||||||
protected EssentialsBridgeableDevice(string key, string name) : base(key, name)
|
protected EssentialsBridgeableDevice(string key, string name) : base(key, name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
|
public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the contract for IHasFeedback
|
/// Defines the contract for IHasFeedback
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasFeedback : IKeyed
|
public interface IHasFeedback : IKeyed
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -19,47 +19,72 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods for IHasFeedback
|
||||||
|
/// </summary>
|
||||||
public static class IHasFeedbackExtensions
|
public static class IHasFeedbackExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the feedback type name for sorting purposes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="feedback">The feedback to get the type name for</param>
|
||||||
|
/// <returns>A string representing the feedback type</returns>
|
||||||
|
private static string GetFeedbackTypeName(Feedback feedback)
|
||||||
|
{
|
||||||
|
if (feedback is BoolFeedback)
|
||||||
|
return "boolean";
|
||||||
|
else if (feedback is IntFeedback)
|
||||||
|
return "integer";
|
||||||
|
else if (feedback is StringFeedback)
|
||||||
|
return "string";
|
||||||
|
else
|
||||||
|
return feedback.GetType().Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dumps the feedbacks to the console
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source"></param>
|
||||||
|
/// <param name="getCurrentStates"></param>
|
||||||
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
||||||
{
|
{
|
||||||
Type t = source.GetType();
|
|
||||||
// get the properties and set them into a new collection of NameType wrappers
|
|
||||||
var props = t.GetProperties().Select(p => new PropertyNameType(p, t));
|
|
||||||
|
|
||||||
var feedbacks = source.Feedbacks;
|
var feedbacks = source.Feedbacks;
|
||||||
if (feedbacks != null)
|
|
||||||
|
if (feedbacks == null || feedbacks.Count == 0)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, source, "\n\nAvailable feedbacks:");
|
CrestronConsole.ConsoleCommandResponse("No available feedbacks\r\n");
|
||||||
foreach (var f in feedbacks)
|
return;
|
||||||
{
|
}
|
||||||
string val = "";
|
|
||||||
string type = "";
|
CrestronConsole.ConsoleCommandResponse("Available feedbacks:\r\n");
|
||||||
if (getCurrentStates)
|
|
||||||
{
|
// Sort feedbacks by type first, then by key
|
||||||
if (f is BoolFeedback)
|
var sortedFeedbacks = feedbacks.OrderBy(f => GetFeedbackTypeName(f)).ThenBy(f => string.IsNullOrEmpty(f.Key) ? "" : f.Key);
|
||||||
{
|
|
||||||
val = f.BoolValue.ToString();
|
foreach (var feedback in sortedFeedbacks)
|
||||||
type = "boolean";
|
{
|
||||||
}
|
string value = "";
|
||||||
else if (f is IntFeedback)
|
string type = "";
|
||||||
{
|
if (getCurrentStates)
|
||||||
val = f.IntValue.ToString();
|
{
|
||||||
type = "integer";
|
if (feedback is BoolFeedback)
|
||||||
}
|
{
|
||||||
else if (f is StringFeedback)
|
value = feedback.BoolValue.ToString();
|
||||||
{
|
type = "boolean";
|
||||||
val = f.StringValue;
|
}
|
||||||
type = "string";
|
else if (feedback is IntFeedback)
|
||||||
}
|
{
|
||||||
}
|
value = feedback.IntValue.ToString();
|
||||||
Debug.LogMessage(LogEventLevel.Information, "{0,-12} {1, -25} {2}", type,
|
type = "integer";
|
||||||
(string.IsNullOrEmpty(f.Key) ? "-no key-" : f.Key), val);
|
}
|
||||||
}
|
else if (feedback is StringFeedback)
|
||||||
|
{
|
||||||
|
value = feedback.StringValue;
|
||||||
|
type = "string";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CrestronConsole.ConsoleCommandResponse($" {type,-12} {(string.IsNullOrEmpty(feedback.Key) ? "-no key-" : feedback.Key),-25} {value}\r\n");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, source, "No available outputs:");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,6 +103,12 @@ namespace PepperDash.Essentials.Core
|
|||||||
[JsonProperty("name")]
|
[JsonProperty("name")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether to hide this scenario in the UI.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("hideInUi", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public bool HideInUi { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the collection of partition states.
|
/// Gets or sets the collection of partition states.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -109,6 +109,12 @@ namespace PepperDash.Essentials.Core
|
|||||||
[JsonProperty("isActive")]
|
[JsonProperty("isActive")]
|
||||||
bool IsActive { get; }
|
bool IsActive { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this scenario should be hidden in the UI.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("hideInUi")]
|
||||||
|
bool HideInUi { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Activates this room combination scenario
|
/// Activates this room combination scenario
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -14,18 +14,40 @@ namespace PepperDash.Essentials.Core
|
|||||||
{
|
{
|
||||||
private RoomCombinationScenarioConfig _config;
|
private RoomCombinationScenarioConfig _config;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the key associated with the object.
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("key")]
|
[JsonProperty("key")]
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the name associated with the object.
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("name")]
|
[JsonProperty("name")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
[JsonProperty("partitionStates")]
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether to hide this scenario in the UI.
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
[JsonProperty("hideInUi")]
|
||||||
|
|
||||||
|
public bool HideInUi
|
||||||
|
{
|
||||||
|
get { return _config.HideInUi; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the PartitionStates
|
/// Gets or sets the PartitionStates
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
///
|
||||||
|
[JsonProperty("partitionStates")]
|
||||||
|
|
||||||
public List<PartitionState> PartitionStates { get; private set; }
|
public List<PartitionState> PartitionStates { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines which UI devices get mapped to which room in this scenario. The Key should be the key of the UI device and the Value should be the key of the room to map to
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("uiMap")]
|
[JsonProperty("uiMap")]
|
||||||
public Dictionary<string, string> UiMap { get; set; }
|
public Dictionary<string, string> UiMap { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Room.Config
|
namespace PepperDash.Essentials.Room.Config
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a EssentialsRoomConfigHelper
|
/// Represents a EssentialsRoomConfigHelper
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsRoomConfigHelper
|
public class EssentialsRoomConfigHelper
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GetEmergency method
|
/// GetEmergency method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -31,100 +31,100 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="props"></param>
|
/// <param name="props"></param>
|
||||||
/// <param name="room"></param>
|
/// <param name="room"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GetMicrophonePrivacy method
|
/// GetMicrophonePrivacy method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static MicrophonePrivacyController GetMicrophonePrivacy(
|
public static MicrophonePrivacyController GetMicrophonePrivacy(
|
||||||
EssentialsRoomPropertiesConfig props, IPrivacy room)
|
EssentialsRoomPropertiesConfig props, IPrivacy room)
|
||||||
{
|
{
|
||||||
var microphonePrivacy = props.MicrophonePrivacy;
|
var microphonePrivacy = props.MicrophonePrivacy;
|
||||||
if (microphonePrivacy == null)
|
if (microphonePrivacy == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Cannot create microphone privacy with null properties");
|
Debug.LogMessage(LogEventLevel.Information, "Cannot create microphone privacy with null properties");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Get the MicrophonePrivacy device from the device manager
|
// Get the MicrophonePrivacy device from the device manager
|
||||||
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as MicrophonePrivacyController);
|
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as MicrophonePrivacyController);
|
||||||
// Set this room as the IPrivacy device
|
// Set this room as the IPrivacy device
|
||||||
if (mP == null)
|
if (mP == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "ERROR: Selected device {0} is not MicrophonePrivacyController", props.MicrophonePrivacy.DeviceKey);
|
Debug.LogMessage(LogEventLevel.Information, "ERROR: Selected device {0} is not MicrophonePrivacyController", props.MicrophonePrivacy.DeviceKey);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
mP.SetPrivacyDevice(room);
|
mP.SetPrivacyDevice(room);
|
||||||
|
|
||||||
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
|
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
|
||||||
|
|
||||||
if (behaviour == null)
|
if (behaviour == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "WARNING: No behaviour defined for MicrophonePrivacyController");
|
Debug.LogMessage(LogEventLevel.Information, "WARNING: No behaviour defined for MicrophonePrivacyController");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (behaviour == "trackroomstate")
|
if (behaviour == "trackroomstate")
|
||||||
{
|
{
|
||||||
// Tie LED enable to room power state
|
// Tie LED enable to room power state
|
||||||
var essRoom = room as IEssentialsRoom;
|
var essRoom = room as IEssentialsRoom;
|
||||||
essRoom.OnFeedback.OutputChange += (o, a) =>
|
essRoom.OnFeedback.OutputChange += (o, a) =>
|
||||||
{
|
{
|
||||||
if (essRoom.OnFeedback.BoolValue)
|
if (essRoom.OnFeedback.BoolValue)
|
||||||
mP.EnableLeds = true;
|
mP.EnableLeds = true;
|
||||||
else
|
else
|
||||||
mP.EnableLeds = false;
|
mP.EnableLeds = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
mP.EnableLeds = essRoom.OnFeedback.BoolValue;
|
mP.EnableLeds = essRoom.OnFeedback.BoolValue;
|
||||||
}
|
}
|
||||||
else if (behaviour == "trackcallstate")
|
else if (behaviour == "trackcallstate")
|
||||||
{
|
{
|
||||||
// Tie LED enable to room power state
|
// Tie LED enable to room power state
|
||||||
var inCallRoom = room as IHasInCallFeedback;
|
var inCallRoom = room as IHasInCallFeedback;
|
||||||
inCallRoom.InCallFeedback.OutputChange += (o, a) =>
|
inCallRoom.InCallFeedback.OutputChange += (o, a) =>
|
||||||
{
|
{
|
||||||
if (inCallRoom.InCallFeedback.BoolValue)
|
if (inCallRoom.InCallFeedback.BoolValue)
|
||||||
mP.EnableLeds = true;
|
mP.EnableLeds = true;
|
||||||
else
|
else
|
||||||
mP.EnableLeds = false;
|
mP.EnableLeds = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
mP.EnableLeds = inCallRoom.InCallFeedback.BoolValue;
|
mP.EnableLeds = inCallRoom.InCallFeedback.BoolValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mP;
|
return mP;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a EssentialsRoomPropertiesConfig
|
/// Represents a EssentialsRoomPropertiesConfig
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsRoomPropertiesConfig
|
public class EssentialsRoomPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("addresses")]
|
[JsonProperty("addresses")]
|
||||||
public EssentialsRoomAddressPropertiesConfig Addresses { get; set; }
|
public EssentialsRoomAddressPropertiesConfig Addresses { get; set; }
|
||||||
|
|
||||||
[JsonProperty("description")]
|
[JsonProperty("description")]
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
[JsonProperty("emergency")]
|
[JsonProperty("emergency")]
|
||||||
public EssentialsRoomEmergencyConfig Emergency { get; set; }
|
public EssentialsRoomEmergencyConfig Emergency { get; set; }
|
||||||
|
|
||||||
[JsonProperty("help")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the Help
|
||||||
/// Gets or sets the Help
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("help")]
|
||||||
public EssentialsHelpPropertiesConfig Help { get; set; }
|
public EssentialsHelpPropertiesConfig Help { get; set; }
|
||||||
|
|
||||||
[JsonProperty("helpMessage")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the HelpMessage
|
||||||
/// Gets or sets the HelpMessage
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("helpMessage")]
|
||||||
public string HelpMessage { get; set; }
|
public string HelpMessage { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read this value to get the help message. It checks for the old and new config format.
|
/// Read this value to get the help message. It checks for the old and new config format.
|
||||||
@@ -133,7 +133,7 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if(Help != null && !string.IsNullOrEmpty(Help.Message))
|
if (Help != null && !string.IsNullOrEmpty(Help.Message))
|
||||||
{
|
{
|
||||||
return Help.Message;
|
return Help.Message;
|
||||||
}
|
}
|
||||||
@@ -144,83 +144,83 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonProperty("environment")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the Environment
|
||||||
/// Gets or sets the Environment
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("environment")]
|
||||||
public EssentialsEnvironmentPropertiesConfig Environment { get; set; }
|
public EssentialsEnvironmentPropertiesConfig Environment { get; set; }
|
||||||
|
|
||||||
[JsonProperty("logo")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the LogoLight
|
||||||
/// Gets or sets the LogoLight
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("logo")]
|
||||||
public EssentialsLogoPropertiesConfig LogoLight { get; set; }
|
public EssentialsLogoPropertiesConfig LogoLight { get; set; }
|
||||||
|
|
||||||
[JsonProperty("logoDark")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the LogoDark
|
/// Gets or sets the LogoDark
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("logoDark")]
|
||||||
public EssentialsLogoPropertiesConfig LogoDark { get; set; }
|
public EssentialsLogoPropertiesConfig LogoDark { get; set; }
|
||||||
|
|
||||||
[JsonProperty("microphonePrivacy")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the MicrophonePrivacy
|
||||||
/// Gets or sets the MicrophonePrivacy
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("microphonePrivacy")]
|
||||||
public EssentialsRoomMicrophonePrivacyConfig MicrophonePrivacy { get; set; }
|
public EssentialsRoomMicrophonePrivacyConfig MicrophonePrivacy { get; set; }
|
||||||
|
|
||||||
[JsonProperty("occupancy")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the Occupancy
|
||||||
/// Gets or sets the Occupancy
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("occupancy")]
|
||||||
public EssentialsRoomOccSensorConfig Occupancy { get; set; }
|
public EssentialsRoomOccSensorConfig Occupancy { get; set; }
|
||||||
|
|
||||||
[JsonProperty("oneButtonMeeting")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the OneButtonMeeting
|
||||||
/// Gets or sets the OneButtonMeeting
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("oneButtonMeeting")]
|
||||||
public EssentialsOneButtonMeetingPropertiesConfig OneButtonMeeting { get; set; }
|
public EssentialsOneButtonMeetingPropertiesConfig OneButtonMeeting { get; set; }
|
||||||
|
|
||||||
[JsonProperty("shutdownVacancySeconds")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the ShutdownVacancySeconds
|
||||||
/// Gets or sets the ShutdownVacancySeconds
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("shutdownVacancySeconds")]
|
||||||
public int ShutdownVacancySeconds { get; set; }
|
public int ShutdownVacancySeconds { get; set; }
|
||||||
|
|
||||||
[JsonProperty("shutdownPromptSeconds")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the ShutdownPromptSeconds
|
||||||
/// Gets or sets the ShutdownPromptSeconds
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("shutdownPromptSeconds")]
|
||||||
public int ShutdownPromptSeconds { get; set; }
|
public int ShutdownPromptSeconds { get; set; }
|
||||||
|
|
||||||
[JsonProperty("tech")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the Tech
|
||||||
/// Gets or sets the Tech
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("tech")]
|
||||||
public EssentialsRoomTechConfig Tech { get; set; }
|
public EssentialsRoomTechConfig Tech { get; set; }
|
||||||
|
|
||||||
[JsonProperty("volumes")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the Volumes
|
||||||
/// Gets or sets the Volumes
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("volumes")]
|
||||||
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
||||||
|
|
||||||
[JsonProperty("fusion")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Fusion
|
/// Gets or sets the Fusion
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("fusion")]
|
||||||
public EssentialsRoomFusionConfig Fusion { get; set; }
|
public EssentialsRoomFusionConfig Fusion { get; set; }
|
||||||
|
|
||||||
[JsonProperty("essentialsRoomUiBehaviorConfig", NullValueHandling=NullValueHandling.Ignore)]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the UiBehavior
|
/// Gets or sets the UiBehavior
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("essentialsRoomUiBehaviorConfig", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
|
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
|
||||||
|
|
||||||
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
|
/// <summary>
|
||||||
/// <summary>
|
/// Gets or sets the ZeroVolumeWhenSwtichingVolumeDevices
|
||||||
/// Gets or sets the ZeroVolumeWhenSwtichingVolumeDevices
|
/// </summary>
|
||||||
/// </summary>
|
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
|
||||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates if this room represents a combination of other rooms
|
/// Indicates if this room represents a combination of other rooms
|
||||||
@@ -236,7 +236,7 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
LogoLight = new EssentialsLogoPropertiesConfig();
|
LogoLight = new EssentialsLogoPropertiesConfig();
|
||||||
LogoDark = new EssentialsLogoPropertiesConfig();
|
LogoDark = new EssentialsLogoPropertiesConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a EssentialsRoomUiBehaviorConfig
|
/// Represents a EssentialsRoomUiBehaviorConfig
|
||||||
@@ -327,15 +327,15 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a EssentialsEnvironmentPropertiesConfig
|
/// Represents a EssentialsEnvironmentPropertiesConfig
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsEnvironmentPropertiesConfig
|
public class EssentialsEnvironmentPropertiesConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Enabled
|
/// Gets or sets the Enabled
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
[JsonProperty("deviceKeys")]
|
[JsonProperty("deviceKeys")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -348,7 +348,7 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
DeviceKeys = new List<string>();
|
DeviceKeys = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a EssentialsRoomFusionConfig
|
/// Represents a EssentialsRoomFusionConfig
|
||||||
@@ -390,17 +390,17 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsRoomMicrophonePrivacyConfig
|
public class EssentialsRoomMicrophonePrivacyConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("deviceKey")]
|
[JsonProperty("deviceKey")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the DeviceKey
|
/// Gets or sets the DeviceKey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DeviceKey { get; set; }
|
public string DeviceKey { get; set; }
|
||||||
|
|
||||||
[JsonProperty("behaviour")]
|
[JsonProperty("behaviour")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Behaviour
|
/// Gets or sets the Behaviour
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Behaviour { get; set; }
|
public string Behaviour { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -408,23 +408,23 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsHelpPropertiesConfig
|
public class EssentialsHelpPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("message")]
|
[JsonProperty("message")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Message
|
/// Gets or sets the Message
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
|
|
||||||
[JsonProperty("showCallButton")]
|
[JsonProperty("showCallButton")]
|
||||||
public bool ShowCallButton { get; set; }
|
public bool ShowCallButton { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defaults to "Call Help Desk"
|
/// Defaults to "Call Help Desk"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("callButtonText")]
|
[JsonProperty("callButtonText")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the CallButtonText
|
/// Gets or sets the CallButtonText
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string CallButtonText { get; set; }
|
public string CallButtonText { get; set; }
|
||||||
|
|
||||||
public EssentialsHelpPropertiesConfig()
|
public EssentialsHelpPropertiesConfig()
|
||||||
{
|
{
|
||||||
@@ -437,23 +437,23 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsOneButtonMeetingPropertiesConfig
|
public class EssentialsOneButtonMeetingPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("enable")]
|
[JsonProperty("enable")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Enable
|
/// Gets or sets the Enable
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enable { get; set; }
|
public bool Enable { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EssentialsRoomAddressPropertiesConfig
|
public class EssentialsRoomAddressPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("phoneNumber")]
|
[JsonProperty("phoneNumber")]
|
||||||
public string PhoneNumber { get; set; }
|
public string PhoneNumber { get; set; }
|
||||||
|
|
||||||
[JsonProperty("sipAddress")]
|
[JsonProperty("sipAddress")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the SipAddress
|
/// Gets or sets the SipAddress
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SipAddress { get; set; }
|
public string SipAddress { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -462,14 +462,14 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsLogoPropertiesConfig
|
public class EssentialsLogoPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("type")]
|
[JsonProperty("type")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Type
|
/// Gets or sets the Type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
|
|
||||||
[JsonProperty("url")]
|
[JsonProperty("url")]
|
||||||
public string Url { get; set; }
|
public string Url { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GetLogoUrlLight method
|
/// GetLogoUrlLight method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -502,22 +502,22 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsRoomOccSensorConfig
|
public class EssentialsRoomOccSensorConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("deviceKey")]
|
[JsonProperty("deviceKey")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the DeviceKey
|
/// Gets or sets the DeviceKey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DeviceKey { get; set; }
|
public string DeviceKey { get; set; }
|
||||||
|
|
||||||
[JsonProperty("timeoutMinutes")]
|
[JsonProperty("timeoutMinutes")]
|
||||||
public int TimeoutMinutes { get; set; }
|
public int TimeoutMinutes { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EssentialsRoomTechConfig
|
public class EssentialsRoomTechConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("password")]
|
[JsonProperty("password")]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Password
|
/// Gets or sets the Password
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,14 +14,14 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
////*****************************************************************************
|
////*****************************************************************************
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// Base class for all subpage reference list controllers
|
///// Base class for all subpage reference list controllers
|
||||||
/// </summary>
|
///// </summary>
|
||||||
//public class SubpageReferenceListController
|
//public class SubpageReferenceListController
|
||||||
//{
|
//{
|
||||||
// public SubpageReferenceList TheList { get; protected set; }
|
// public SubpageReferenceList TheList { get; protected set; }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -34,26 +34,26 @@ namespace PepperDash.Essentials.Core
|
|||||||
public ushort Count
|
public ushort Count
|
||||||
{
|
{
|
||||||
get { return SetNumberOfItemsSig.UShortValue; }
|
get { return SetNumberOfItemsSig.UShortValue; }
|
||||||
set { SetNumberOfItemsSig.UShortValue = value; }
|
set { SetNumberOfItemsSig.UShortValue = value; }
|
||||||
}
|
}
|
||||||
public ushort MaxDefinedItems { get; private set; }
|
public ushort MaxDefinedItems { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the ScrollToItemSig
|
/// Gets or sets the ScrollToItemSig
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UShortInputSig ScrollToItemSig { get; private set; }
|
public UShortInputSig ScrollToItemSig { get; private set; }
|
||||||
UShortInputSig SetNumberOfItemsSig;
|
UShortInputSig SetNumberOfItemsSig;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the BoolIncrement
|
/// Gets or sets the BoolIncrement
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint BoolIncrement { get; protected set; }
|
public uint BoolIncrement { get; protected set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the UShortIncrement
|
/// Gets or sets the UShortIncrement
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint UShortIncrement { get; protected set; }
|
public uint UShortIncrement { get; protected set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the StringIncrement
|
/// Gets or sets the StringIncrement
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint StringIncrement { get; protected set; }
|
public uint StringIncrement { get; protected set; }
|
||||||
|
|
||||||
protected readonly SmartObject SRL;
|
protected readonly SmartObject SRL;
|
||||||
@@ -88,7 +88,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
Debug.LogMessage(LogEventLevel.Information, "ERROR: TriList 0x{0:X2} Cannot load smart object {1}. Verify correct SGD file is loaded",
|
Debug.LogMessage(LogEventLevel.Information, "ERROR: TriList 0x{0:X2} Cannot load smart object {1}. Verify correct SGD file is loaded",
|
||||||
triList.ID, smartObjectId);
|
triList.ID, smartObjectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -96,17 +96,17 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// DOES NOT adjust Count
|
/// DOES NOT adjust Count
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item"></param>
|
/// <param name="item"></param>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// AddItem method
|
/// AddItem method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void AddItem(SubpageReferenceListItem item)
|
public void AddItem(SubpageReferenceListItem item)
|
||||||
{
|
{
|
||||||
Items.Add(item);
|
Items.Add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clear method
|
/// Clear method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
// If a line item needs to disconnect an CueActionPair or do something to release RAM
|
// If a line item needs to disconnect an CueActionPair or do something to release RAM
|
||||||
@@ -116,12 +116,12 @@ namespace PepperDash.Essentials.Core
|
|||||||
// Clean up the SRL
|
// Clean up the SRL
|
||||||
Count = 1;
|
Count = 1;
|
||||||
|
|
||||||
ScrollToItemSig.UShortValue = 1;
|
ScrollToItemSig.UShortValue = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Refresh method
|
/// Refresh method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Refresh()
|
public void Refresh()
|
||||||
{
|
{
|
||||||
foreach (var item in Items) item.Refresh();
|
foreach (var item in Items) item.Refresh();
|
||||||
@@ -157,7 +157,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
public UShortOutputSig GetUShortOutputSig(uint index, uint sigNum)
|
public UShortOutputSig GetUShortOutputSig(uint index, uint sigNum)
|
||||||
{
|
{
|
||||||
if (sigNum > UShortIncrement) return null;
|
if (sigNum > UShortIncrement) return null;
|
||||||
return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetUShortOutputSigName(index, sigNum)));
|
return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetUShortOutputSigName(index, sigNum)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -172,7 +172,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
public StringOutputSig GetStringOutputSig(uint index, uint sigNum)
|
public StringOutputSig GetStringOutputSig(uint index, uint sigNum)
|
||||||
{
|
{
|
||||||
if (sigNum > StringIncrement) return null;
|
if (sigNum > StringIncrement) return null;
|
||||||
return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetStringOutputSigName(index, sigNum)));
|
return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetStringOutputSigName(index, sigNum)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -263,9 +263,9 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="currentDevice"></param>
|
/// <param name="currentDevice"></param>
|
||||||
/// <param name="args"></param>
|
/// <param name="args"></param>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SRL_SigChange method
|
/// SRL_SigChange method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SRL_SigChange(GenericBase currentDevice, SmartObjectEventArgs args)
|
public static void SRL_SigChange(GenericBase currentDevice, SmartObjectEventArgs args)
|
||||||
{
|
{
|
||||||
var uo = args.Sig.UserObject;
|
var uo = args.Sig.UserObject;
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a ModalDialog
|
/// Represents a ModalDialog
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ModalDialog
|
public class ModalDialog
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -19,10 +19,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// Bool press 3992
|
/// Bool press 3992
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint Button2Join = 3992;
|
public const uint Button2Join = 3992;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 3993
|
/// 3993
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint CancelButtonJoin = 3993;
|
public const uint CancelButtonJoin = 3993;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///For visibility of single button. Bool feedback 3994
|
///For visibility of single button. Bool feedback 3994
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -35,19 +35,19 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// Shows the timer guage if in use. Bool feedback 3996
|
/// Shows the timer guage if in use. Bool feedback 3996
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint TimerVisibleJoin = 3996;
|
public const uint TimerVisibleJoin = 3996;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Visibility join to show "X" button 3997
|
/// Visibility join to show "X" button 3997
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint CancelVisibleJoin = 3997;
|
public const uint CancelVisibleJoin = 3997;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows the modal subpage. Boolean feeback join 3999
|
/// Shows the modal subpage. Boolean feeback join 3999
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint ModalVisibleJoin = 3999;
|
public const uint ModalVisibleJoin = 3999;
|
||||||
|
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// The seconds value of the countdown timer. Ushort join 3991
|
///// The seconds value of the countdown timer. Ushort join 3991
|
||||||
/// </summary>
|
///// </summary>
|
||||||
//public const uint TimerSecondsJoin = 3991;
|
//public const uint TimerSecondsJoin = 3991;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The full ushort value of the countdown timer for a gauge. Ushort join 3992
|
/// The full ushort value of the countdown timer for a gauge. Ushort join 3992
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -82,10 +82,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
get { return TriList.BooleanInput[ModalVisibleJoin].BoolValue; }
|
get { return TriList.BooleanInput[ModalVisibleJoin].BoolValue; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CanCancel { get; private set; }
|
public bool CanCancel { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
BasicTriList TriList;
|
BasicTriList TriList;
|
||||||
@@ -103,10 +103,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
TriList = triList;
|
TriList = triList;
|
||||||
// Attach actions to buttons
|
// Attach actions to buttons
|
||||||
|
|
||||||
triList.SetSigFalseAction(Button1Join, () => OnModalComplete(1));
|
triList.SetSigFalseAction(Button1Join, () => OnModalComplete(1));
|
||||||
triList.SetSigFalseAction(Button2Join, () => OnModalComplete(2));
|
triList.SetSigFalseAction(Button2Join, () => OnModalComplete(2));
|
||||||
triList.SetSigFalseAction(CancelButtonJoin, () => { if (CanCancel) CancelDialog(); });
|
triList.SetSigFalseAction(CancelButtonJoin, () => { if (CanCancel) CancelDialog(); });
|
||||||
CanCancel = true;
|
CanCancel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -151,15 +151,15 @@ namespace PepperDash.Essentials.Core
|
|||||||
TriList.StringInput[Button2TextJoin].StringValue = button2Text;
|
TriList.StringInput[Button2TextJoin].StringValue = button2Text;
|
||||||
}
|
}
|
||||||
// Show/hide guage
|
// Show/hide guage
|
||||||
TriList.BooleanInput[TimerVisibleJoin].BoolValue = showGauge;
|
TriList.BooleanInput[TimerVisibleJoin].BoolValue = showGauge;
|
||||||
|
|
||||||
CanCancel = showCancel;
|
CanCancel = showCancel;
|
||||||
TriList.BooleanInput[CancelVisibleJoin].BoolValue = showCancel;
|
TriList.BooleanInput[CancelVisibleJoin].BoolValue = showCancel;
|
||||||
|
|
||||||
//Reveal and activate
|
//Reveal and activate
|
||||||
TriList.BooleanInput[ModalVisibleJoin].BoolValue = true;
|
TriList.BooleanInput[ModalVisibleJoin].BoolValue = true;
|
||||||
|
|
||||||
WakePanel();
|
WakePanel();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -167,48 +167,48 @@ namespace PepperDash.Essentials.Core
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WakePanel method
|
/// WakePanel method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void WakePanel()
|
public void WakePanel()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var panel = TriList as TswFt5Button;
|
|
||||||
|
|
||||||
if (panel != null && panel.ExtenderSystemReservedSigs.BacklightOffFeedback.BoolValue)
|
|
||||||
panel.ExtenderSystemReservedSigs.BacklightOn();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Error Waking Panel. Maybe testing with Xpanel?");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// CancelDialog method
|
|
||||||
/// </summary>
|
|
||||||
public void CancelDialog()
|
|
||||||
{
|
{
|
||||||
OnModalComplete(0);
|
try
|
||||||
|
{
|
||||||
|
var panel = TriList as TswFt5Button;
|
||||||
|
|
||||||
|
if (panel != null && panel.ExtenderSystemReservedSigs.BacklightOffFeedback.BoolValue)
|
||||||
|
panel.ExtenderSystemReservedSigs.BacklightOn();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Debug, "Error Waking Panel. Maybe testing with Xpanel?");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hides dialog. Fires no action
|
/// CancelDialog method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void HideDialog()
|
public void CancelDialog()
|
||||||
{
|
{
|
||||||
TriList.BooleanInput[ModalVisibleJoin].BoolValue = false;
|
OnModalComplete(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Hides dialog. Fires no action
|
||||||
|
/// </summary>
|
||||||
|
public void HideDialog()
|
||||||
|
{
|
||||||
|
TriList.BooleanInput[ModalVisibleJoin].BoolValue = false;
|
||||||
|
}
|
||||||
|
|
||||||
// When the modal is cleared or times out, clean up the various bits
|
// When the modal is cleared or times out, clean up the various bits
|
||||||
void OnModalComplete(uint buttonNum)
|
void OnModalComplete(uint buttonNum)
|
||||||
{
|
{
|
||||||
TriList.BooleanInput[ModalVisibleJoin].BoolValue = false;
|
TriList.BooleanInput[ModalVisibleJoin].BoolValue = false;
|
||||||
|
|
||||||
var action = ModalCompleteAction;
|
var action = ModalCompleteAction;
|
||||||
if (action != null)
|
if (action != null)
|
||||||
action(buttonNum);
|
action(buttonNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,221 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using PepperDash.Core;
|
|
||||||
using PepperDash.Core.Logging;
|
|
||||||
using PepperDash.Essentials.Core;
|
|
||||||
using PepperDash.Essentials.Devices.Common.Codec;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.AppServer.Messengers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Provides a messaging bridge for devices that implement call status interfaces
|
|
||||||
/// without requiring VideoCodecBase inheritance
|
|
||||||
/// </summary>
|
|
||||||
public class CallStatusMessenger : MessengerBase
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Device with dialer capabilities
|
|
||||||
/// </summary>
|
|
||||||
protected IHasDialer Dialer { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Device with content sharing capabilities (optional)
|
|
||||||
/// </summary>
|
|
||||||
protected IHasContentSharing ContentSharing { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="key"></param>
|
|
||||||
/// <param name="dialer"></param>
|
|
||||||
/// <param name="messagePath"></param>
|
|
||||||
public CallStatusMessenger(string key, IHasDialer dialer, string messagePath)
|
|
||||||
: base(key, messagePath, dialer as IKeyName)
|
|
||||||
{
|
|
||||||
Dialer = dialer ?? throw new ArgumentNullException(nameof(dialer));
|
|
||||||
dialer.CallStatusChange += Dialer_CallStatusChange;
|
|
||||||
|
|
||||||
// Check for optional content sharing interface
|
|
||||||
if (dialer is IHasContentSharing contentSharing)
|
|
||||||
{
|
|
||||||
ContentSharing = contentSharing;
|
|
||||||
contentSharing.SharingContentIsOnFeedback.OutputChange += SharingContentIsOnFeedback_OutputChange;
|
|
||||||
contentSharing.SharingSourceFeedback.OutputChange += SharingSourceFeedback_OutputChange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles call status changes
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void Dialer_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SendFullStatus();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
this.LogError(ex, "Error handling call status change: {error}", ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles content sharing status changes
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void SharingContentIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
|
||||||
{
|
|
||||||
PostStatusMessage(JToken.FromObject(new
|
|
||||||
{
|
|
||||||
sharingContentIsOn = e.BoolValue
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles sharing source changes
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void SharingSourceFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
|
||||||
{
|
|
||||||
PostStatusMessage(JToken.FromObject(new
|
|
||||||
{
|
|
||||||
sharingSource = e.StringValue
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets active calls from the dialer
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
private object GetActiveCalls()
|
|
||||||
{
|
|
||||||
// Try to get active calls if the dialer has an ActiveCalls property
|
|
||||||
var dialerType = Dialer.GetType();
|
|
||||||
var activeCallsProperty = dialerType.GetProperty("ActiveCalls");
|
|
||||||
|
|
||||||
if (activeCallsProperty != null && activeCallsProperty.PropertyType == typeof(System.Collections.Generic.List<CodecActiveCallItem>))
|
|
||||||
{
|
|
||||||
var activeCalls = activeCallsProperty.GetValue(Dialer) as System.Collections.Generic.List<CodecActiveCallItem>;
|
|
||||||
return activeCalls ?? new System.Collections.Generic.List<CodecActiveCallItem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return basic call status if no ActiveCalls property
|
|
||||||
return new { isInCall = Dialer.IsInCall };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sends full status message
|
|
||||||
/// </summary>
|
|
||||||
public void SendFullStatus()
|
|
||||||
{
|
|
||||||
var status = new
|
|
||||||
{
|
|
||||||
isInCall = Dialer.IsInCall,
|
|
||||||
calls = GetActiveCalls()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add content sharing status if available
|
|
||||||
if (ContentSharing != null)
|
|
||||||
{
|
|
||||||
var statusWithSharing = new
|
|
||||||
{
|
|
||||||
isInCall = Dialer.IsInCall,
|
|
||||||
calls = GetActiveCalls(),
|
|
||||||
sharingContentIsOn = ContentSharing.SharingContentIsOnFeedback.BoolValue,
|
|
||||||
sharingSource = ContentSharing.SharingSourceFeedback.StringValue
|
|
||||||
};
|
|
||||||
PostStatusMessage(JToken.FromObject(statusWithSharing));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PostStatusMessage(JToken.FromObject(status));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers actions for call control
|
|
||||||
/// </summary>
|
|
||||||
protected override void RegisterActions()
|
|
||||||
{
|
|
||||||
base.RegisterActions();
|
|
||||||
|
|
||||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
|
||||||
|
|
||||||
// Basic call control actions
|
|
||||||
AddAction("/dial", (id, content) =>
|
|
||||||
{
|
|
||||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
|
||||||
Dialer.Dial(msg.Value);
|
|
||||||
});
|
|
||||||
|
|
||||||
AddAction("/endAllCalls", (id, content) => Dialer.EndAllCalls());
|
|
||||||
|
|
||||||
AddAction("/dtmf", (id, content) =>
|
|
||||||
{
|
|
||||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
|
||||||
Dialer.SendDtmf(msg.Value);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Call-specific actions (if active calls are available)
|
|
||||||
AddAction("/endCallById", (id, content) =>
|
|
||||||
{
|
|
||||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
|
||||||
var call = GetCallWithId(msg.Value);
|
|
||||||
if (call != null)
|
|
||||||
Dialer.EndCall(call);
|
|
||||||
});
|
|
||||||
|
|
||||||
AddAction("/acceptById", (id, content) =>
|
|
||||||
{
|
|
||||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
|
||||||
var call = GetCallWithId(msg.Value);
|
|
||||||
if (call != null)
|
|
||||||
Dialer.AcceptCall(call);
|
|
||||||
});
|
|
||||||
|
|
||||||
AddAction("/rejectById", (id, content) =>
|
|
||||||
{
|
|
||||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
|
||||||
var call = GetCallWithId(msg.Value);
|
|
||||||
if (call != null)
|
|
||||||
Dialer.RejectCall(call);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Content sharing actions if available
|
|
||||||
if (ContentSharing != null)
|
|
||||||
{
|
|
||||||
AddAction("/startSharing", (id, content) => ContentSharing.StartSharing());
|
|
||||||
AddAction("/stopSharing", (id, content) => ContentSharing.StopSharing());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds a call by ID
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private CodecActiveCallItem GetCallWithId(string id)
|
|
||||||
{
|
|
||||||
// Try to get call using reflection for ActiveCalls property
|
|
||||||
var dialerType = Dialer.GetType();
|
|
||||||
var activeCallsProperty = dialerType.GetProperty("ActiveCalls");
|
|
||||||
|
|
||||||
if (activeCallsProperty != null && activeCallsProperty.PropertyType == typeof(System.Collections.Generic.List<CodecActiveCallItem>))
|
|
||||||
{
|
|
||||||
var activeCalls = activeCallsProperty.GetValue(Dialer) as System.Collections.Generic.List<CodecActiveCallItem>;
|
|
||||||
if (activeCalls != null)
|
|
||||||
{
|
|
||||||
return activeCalls.FirstOrDefault(c => c.Id.Equals(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -140,17 +140,19 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
|
|
||||||
if (Camera is IHasCameraPresets presetsCamera)
|
if (Camera is IHasCameraPresets presetsCamera)
|
||||||
{
|
{
|
||||||
for (int i = 1; i <= 6; i++)
|
AddAction("/recallPreset", (id, content) =>
|
||||||
{
|
{
|
||||||
var preset = i;
|
var msg = content.ToObject<MobileControlSimpleContent<int>>();
|
||||||
AddAction("/cameraPreset" + i, (id, content) =>
|
|
||||||
{
|
|
||||||
var msg = content.ToObject<MobileControlSimpleContent<int>>();
|
|
||||||
|
|
||||||
presetsCamera.PresetSelect(msg.Value);
|
presetsCamera.PresetSelect(msg.Value);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
AddAction("/storePreset", (id, content) =>
|
||||||
|
{
|
||||||
|
var msg = content.ToObject<MobileControlSimpleContent<int>>();
|
||||||
|
|
||||||
|
presetsCamera.PresetStore(msg.Value, string.Empty);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,9 +166,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
timerHandler(state.Value, cameraAction);
|
timerHandler(Camera.Key, cameraAction);
|
||||||
|
|
||||||
cameraAction(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a IBasicVideoMuteWithFeedbackMessenger
|
||||||
|
/// </summary>
|
||||||
|
public class IBasicVideoMuteWithFeedbackMessenger : MessengerBase
|
||||||
|
{
|
||||||
|
private readonly IBasicVideoMuteWithFeedback device;
|
||||||
|
|
||||||
|
public IBasicVideoMuteWithFeedbackMessenger(string key, string messagePath, IBasicVideoMuteWithFeedback device)
|
||||||
|
: base(key, messagePath, device as IKeyName)
|
||||||
|
{
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SendFullStatus method
|
||||||
|
/// </summary>
|
||||||
|
public void SendFullStatus()
|
||||||
|
{
|
||||||
|
var messageObj = new IBasicVideoMuteWithFeedbackMessage
|
||||||
|
{
|
||||||
|
VideoMuteState = device.VideoMuteIsOn.BoolValue
|
||||||
|
};
|
||||||
|
|
||||||
|
PostStatusMessage(messageObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void RegisterActions()
|
||||||
|
{
|
||||||
|
base.RegisterActions();
|
||||||
|
|
||||||
|
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||||
|
|
||||||
|
AddAction("/videoMuteToggle", (id, content) =>
|
||||||
|
{
|
||||||
|
device.VideoMuteToggle();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAction("/videoMuteOn", (id, content) =>
|
||||||
|
{
|
||||||
|
device.VideoMuteOn();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAction("/videoMuteOff", (id, content) =>
|
||||||
|
{
|
||||||
|
device.VideoMuteOff();
|
||||||
|
});
|
||||||
|
|
||||||
|
device.VideoMuteIsOn.OutputChange += VideoMuteIsOnFeedback_OutputChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VideoMuteIsOnFeedback_OutputChange(object sender, FeedbackEventArgs args)
|
||||||
|
{
|
||||||
|
PostStatusMessage(JToken.FromObject(new
|
||||||
|
{
|
||||||
|
videoMuteState = args.BoolValue
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a IBasicVideoMuteWithFeedbackMessage
|
||||||
|
/// </summary>
|
||||||
|
public class IBasicVideoMuteWithFeedbackMessage : DeviceStateMessageBase
|
||||||
|
{
|
||||||
|
[JsonProperty("videoMuteState")]
|
||||||
|
public bool VideoMuteState { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using Newtonsoft.Json;
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials
|
namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
@@ -9,25 +9,34 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MobileControlConfig
|
public class MobileControlConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the ServerUrl
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("serverUrl")]
|
[JsonProperty("serverUrl")]
|
||||||
public string ServerUrl { get; set; }
|
public string ServerUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the ClientAppUrl
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("clientAppUrl")]
|
[JsonProperty("clientAppUrl")]
|
||||||
public string ClientAppUrl { get; set; }
|
public string ClientAppUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the DirectServer
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("directServer")]
|
[JsonProperty("directServer")]
|
||||||
public MobileControlDirectServerPropertiesConfig DirectServer { get; set; }
|
public MobileControlDirectServerPropertiesConfig DirectServer { get; set; }
|
||||||
|
|
||||||
[JsonProperty("applicationConfig")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the ApplicationConfig
|
/// Gets or sets the ApplicationConfig
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("applicationConfig")]
|
||||||
public MobileControlApplicationConfig ApplicationConfig { get; set; } = null;
|
public MobileControlApplicationConfig ApplicationConfig { get; set; } = null;
|
||||||
|
|
||||||
[JsonProperty("enableApiServer")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the EnableApiServer
|
/// Gets or sets the EnableApiServer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("enableApiServer")]
|
||||||
public bool EnableApiServer { get; set; } = true;
|
public bool EnableApiServer { get; set; } = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,27 +45,42 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MobileControlDirectServerPropertiesConfig
|
public class MobileControlDirectServerPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("enableDirectServer")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the EnableDirectServer
|
/// Gets or sets the EnableDirectServer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("enableDirectServer")]
|
||||||
public bool EnableDirectServer { get; set; }
|
public bool EnableDirectServer { get; set; }
|
||||||
|
|
||||||
[JsonProperty("port")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Port
|
/// Gets or sets the Port
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("port")]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
[JsonProperty("logging")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Logging
|
/// Gets or sets the Logging
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("logging")]
|
||||||
public MobileControlLoggingConfig Logging { get; set; }
|
public MobileControlLoggingConfig Logging { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the AutomaticallyForwardPortToCSLAN
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("automaticallyForwardPortToCSLAN")]
|
[JsonProperty("automaticallyForwardPortToCSLAN")]
|
||||||
public bool? AutomaticallyForwardPortToCSLAN { get; set; }
|
public bool? AutomaticallyForwardPortToCSLAN { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the CSLanUiDeviceKeys
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// A list of device keys for the CS LAN UI. These devices will get the CS LAN IP address instead of the LAN IP Address
|
||||||
|
/// </remarks>
|
||||||
|
[JsonProperty("csLanUiDeviceKeys")]
|
||||||
|
public List<string> CSLanUiDeviceKeys { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the MobileControlDirectServerPropertiesConfig class.
|
||||||
|
/// </summary>
|
||||||
public MobileControlDirectServerPropertiesConfig()
|
public MobileControlDirectServerPropertiesConfig()
|
||||||
{
|
{
|
||||||
Logging = new MobileControlLoggingConfig();
|
Logging = new MobileControlLoggingConfig();
|
||||||
@@ -68,26 +92,26 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MobileControlLoggingConfig
|
public class MobileControlLoggingConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("enableRemoteLogging")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the EnableRemoteLogging
|
/// Gets or sets the EnableRemoteLogging
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("enableRemoteLogging")]
|
||||||
public bool EnableRemoteLogging { get; set; }
|
public bool EnableRemoteLogging { get; set; }
|
||||||
|
|
||||||
[JsonProperty("host")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Host
|
/// Gets or sets the Host
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("host")]
|
||||||
public string Host { get; set; }
|
public string Host { get; set; }
|
||||||
|
|
||||||
[JsonProperty("port")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Port
|
/// Gets or sets the Port
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("port")]
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -95,16 +119,16 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MobileControlRoomBridgePropertiesConfig
|
public class MobileControlRoomBridgePropertiesConfig
|
||||||
{
|
{
|
||||||
[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("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; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,53 +137,71 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MobileControlSimplRoomBridgePropertiesConfig
|
public class MobileControlSimplRoomBridgePropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("eiscId")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the EiscId
|
/// Gets or sets the EiscId
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("eiscId")]
|
||||||
public string EiscId { get; set; }
|
public string EiscId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a MobileControlApplicationConfig
|
||||||
|
/// </summary>
|
||||||
public class MobileControlApplicationConfig
|
public class MobileControlApplicationConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the ApiPath
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("apiPath")]
|
[JsonProperty("apiPath")]
|
||||||
public string ApiPath { get; set; }
|
public string ApiPath { get; set; }
|
||||||
|
|
||||||
[JsonProperty("gatewayAppPath")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the GatewayAppPath
|
/// Gets or sets the GatewayAppPath
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("gatewayAppPath")]
|
||||||
public string GatewayAppPath { get; set; }
|
public string GatewayAppPath { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the EnableDev
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("enableDev")]
|
[JsonProperty("enableDev")]
|
||||||
public bool? EnableDev { get; set; }
|
public bool? EnableDev { get; set; }
|
||||||
|
|
||||||
[JsonProperty("logoPath")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the LogoPath
|
/// Gets or sets the LogoPath
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("logoPath")]
|
||||||
public string LogoPath { get; set; }
|
public string LogoPath { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the IconSet
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("iconSet")]
|
[JsonProperty("iconSet")]
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public MCIconSet? IconSet { get; set; }
|
public MCIconSet? IconSet { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the LoginMode
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("loginMode")]
|
[JsonProperty("loginMode")]
|
||||||
public string LoginMode { get; set; }
|
public string LoginMode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the Modes
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("modes")]
|
[JsonProperty("modes")]
|
||||||
public Dictionary<string, McMode> Modes { get; set; }
|
public Dictionary<string, McMode> Modes { get; set; }
|
||||||
|
|
||||||
[JsonProperty("enableRemoteLogging")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Logging
|
/// Gets or sets the Logging
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("enableRemoteLogging")]
|
||||||
public bool Logging { get; set; }
|
public bool Logging { get; set; }
|
||||||
|
|
||||||
[JsonProperty("partnerMetadata", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the PartnerMetadata
|
/// Gets or sets the PartnerMetadata
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("partnerMetadata", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public List<MobileControlPartnerMetadata> PartnerMetadata { get; set; }
|
public List<MobileControlPartnerMetadata> PartnerMetadata { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,22 +210,22 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MobileControlPartnerMetadata
|
public class MobileControlPartnerMetadata
|
||||||
{
|
{
|
||||||
[JsonProperty("role")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Role
|
/// Gets or sets the Role
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("role")]
|
||||||
public string Role { get; set; }
|
public string Role { get; set; }
|
||||||
|
|
||||||
[JsonProperty("description")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Description
|
/// Gets or sets the Description
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("description")]
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
[JsonProperty("logoPath")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the LogoPath
|
/// Gets or sets the LogoPath
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("logoPath")]
|
||||||
public string LogoPath { get; set; }
|
public string LogoPath { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,21 +234,22 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class McMode
|
public class McMode
|
||||||
{
|
{
|
||||||
[JsonProperty("listPageText")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the ListPageText
|
/// Gets or sets the ListPageText
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("listPageText")]
|
||||||
public string ListPageText { get; set; }
|
public string ListPageText { get; set; }
|
||||||
[JsonProperty("loginHelpText")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the LoginHelpText
|
/// Gets or sets the LoginHelpText
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("loginHelpText")]
|
||||||
public string LoginHelpText { get; set; }
|
public string LoginHelpText { get; set; }
|
||||||
|
|
||||||
[JsonProperty("passcodePageText")]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the PasscodePageText
|
/// Gets or sets the PasscodePageText
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("passcodePageText")]
|
||||||
public string PasscodePageText { get; set; }
|
public string PasscodePageText { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,8 +258,19 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum MCIconSet
|
public enum MCIconSet
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Google icon set
|
||||||
|
/// </summary>
|
||||||
GOOGLE,
|
GOOGLE,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Habanero icon set
|
||||||
|
/// </summary>
|
||||||
HABANERO,
|
HABANERO,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Neo icon set
|
||||||
|
/// </summary>
|
||||||
NEO
|
NEO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,6 @@ using PepperDash.Essentials.Core.Shades;
|
|||||||
using PepperDash.Essentials.Core.Web;
|
using PepperDash.Essentials.Core.Web;
|
||||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||||
using PepperDash.Essentials.Devices.Common.Codec;
|
|
||||||
using PepperDash.Essentials.Devices.Common.Displays;
|
using PepperDash.Essentials.Devices.Common.Displays;
|
||||||
using PepperDash.Essentials.Devices.Common.Lighting;
|
using PepperDash.Essentials.Devices.Common.Lighting;
|
||||||
using PepperDash.Essentials.Devices.Common.SoftCodec;
|
using PepperDash.Essentials.Devices.Common.SoftCodec;
|
||||||
@@ -506,6 +505,25 @@ namespace PepperDash.Essentials
|
|||||||
messengerAdded = true;
|
messengerAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device is IBasicVideoMuteWithFeedback)
|
||||||
|
{
|
||||||
|
var deviceKey = device.Key;
|
||||||
|
this.LogVerbose(
|
||||||
|
"Adding IBasicVideoMuteWithFeedback for {deviceKey}",
|
||||||
|
deviceKey
|
||||||
|
);
|
||||||
|
|
||||||
|
var videoMuteControlDevice = device as IBasicVideoMuteWithFeedback;
|
||||||
|
var messenger = new IBasicVideoMuteWithFeedbackMessenger(
|
||||||
|
$"{device.Key}-videoMute-{Key}",
|
||||||
|
string.Format("/device/{0}", deviceKey),
|
||||||
|
videoMuteControlDevice
|
||||||
|
);
|
||||||
|
AddDefaultDeviceMessenger(messenger);
|
||||||
|
|
||||||
|
messengerAdded = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (device is ILightingScenes || device is LightingBase)
|
if (device is ILightingScenes || device is LightingBase)
|
||||||
{
|
{
|
||||||
var deviceKey = device.Key;
|
var deviceKey = device.Key;
|
||||||
@@ -561,21 +579,6 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
messengerAdded = true;
|
messengerAdded = true;
|
||||||
}
|
}
|
||||||
else if (device is IHasDialer dialer && !messengerAdded)
|
|
||||||
{
|
|
||||||
this.LogVerbose(
|
|
||||||
"Adding CallStatusMessenger for {deviceKey}", device.Key);
|
|
||||||
|
|
||||||
var messenger = new CallStatusMessenger(
|
|
||||||
$"{device.Key}-callStatus-{Key}",
|
|
||||||
dialer,
|
|
||||||
$"/device/{device.Key}"
|
|
||||||
);
|
|
||||||
|
|
||||||
AddDefaultDeviceMessenger(messenger);
|
|
||||||
|
|
||||||
messengerAdded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device is AudioCodecBase audioCodec)
|
if (device is AudioCodecBase audioCodec)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
using Crestron.SimplSharpPro;
|
using Crestron.SimplSharpPro;
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
using Crestron.SimplSharpPro.UI;
|
using Crestron.SimplSharpPro.UI;
|
||||||
@@ -106,6 +108,11 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
|
|
||||||
public ReadOnlyCollection<ConnectedIpInformation> ConnectedIps => Panel.ConnectedIpList;
|
public ReadOnlyCollection<ConnectedIpInformation> ConnectedIps => Panel.ConnectedIpList;
|
||||||
|
|
||||||
|
private System.Net.IPAddress csIpAddress;
|
||||||
|
|
||||||
|
private System.Net.IPAddress csSubnetMask;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the MobileControlTouchpanelController class.
|
/// Initializes a new instance of the MobileControlTouchpanelController class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -182,6 +189,13 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
};
|
};
|
||||||
|
|
||||||
RegisterForExtenders();
|
RegisterForExtenders();
|
||||||
|
|
||||||
|
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
|
||||||
|
var csSubnetMask = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, csAdapterId);
|
||||||
|
var csIpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
|
||||||
|
|
||||||
|
this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask);
|
||||||
|
this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -381,19 +395,81 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
McServerUrlFeedback.LinkInputSig(Panel.StringInput[3]);
|
McServerUrlFeedback.LinkInputSig(Panel.StringInput[3]);
|
||||||
UserCodeFeedback.LinkInputSig(Panel.StringInput[4]);
|
UserCodeFeedback.LinkInputSig(Panel.StringInput[4]);
|
||||||
|
|
||||||
|
Panel.IpInformationChange += (sender, args) =>
|
||||||
|
{
|
||||||
|
if (args.Connected)
|
||||||
|
{
|
||||||
|
this.LogVerbose("Connection from IP: {ip}", args.DeviceIpAddress);
|
||||||
|
this.LogInformation("Sending {appUrl} on join 1", AppUrlFeedback.StringValue);
|
||||||
|
|
||||||
|
var appUrl = GetUrlWithCorrectIp(_appUrl);
|
||||||
|
Panel.StringInput[1].StringValue = appUrl;
|
||||||
|
|
||||||
|
SetAppUrl(appUrl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.LogVerbose("Disconnection from IP: {ip}", args.DeviceIpAddress);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Panel.OnlineStatusChange += (sender, args) =>
|
Panel.OnlineStatusChange += (sender, args) =>
|
||||||
{
|
{
|
||||||
UpdateFeedbacks();
|
|
||||||
|
|
||||||
this.LogInformation("Sending {appUrl} on join 1", AppUrlFeedback.StringValue);
|
this.LogInformation("Sending {appUrl} on join 1", AppUrlFeedback.StringValue);
|
||||||
|
|
||||||
Panel.StringInput[1].StringValue = AppUrlFeedback.StringValue;
|
UpdateFeedbacks();
|
||||||
|
Panel.StringInput[1].StringValue = _appUrl;
|
||||||
Panel.StringInput[2].StringValue = QrCodeUrlFeedback.StringValue;
|
Panel.StringInput[2].StringValue = QrCodeUrlFeedback.StringValue;
|
||||||
Panel.StringInput[3].StringValue = McServerUrlFeedback.StringValue;
|
Panel.StringInput[3].StringValue = McServerUrlFeedback.StringValue;
|
||||||
Panel.StringInput[4].StringValue = UserCodeFeedback.StringValue;
|
Panel.StringInput[4].StringValue = UserCodeFeedback.StringValue;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the URL with the correct IP address based on the connected devices and the Crestron processor's IP address.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private string GetUrlWithCorrectIp(string url)
|
||||||
|
{
|
||||||
|
var lanAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetLANAdapter);
|
||||||
|
|
||||||
|
var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, lanAdapterId);
|
||||||
|
|
||||||
|
if(csIpAddress == null || csSubnetMask == null || url == null)
|
||||||
|
{
|
||||||
|
this.LogWarning("CS IP Address Subnet Mask or url is null, cannot determine correct IP for URL");
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.LogVerbose("Processor IP: {processorIp}, CS IP: {csIpAddress}, CS Subnet Mask: {csSubnetMask}", processorIp, csIpAddress, csSubnetMask);
|
||||||
|
this.LogVerbose("Connected IP Count: {connectedIps}", ConnectedIps.Count);
|
||||||
|
|
||||||
|
var ip = ConnectedIps.Any(ipInfo =>
|
||||||
|
{
|
||||||
|
if (System.Net.IPAddress.TryParse(ipInfo.DeviceIpAddress, out var parsedIp))
|
||||||
|
{
|
||||||
|
return csIpAddress.IsInSameSubnet(parsedIp, csSubnetMask);
|
||||||
|
}
|
||||||
|
this.LogWarning("Invalid IP address: {deviceIpAddress}", ipInfo.DeviceIpAddress);
|
||||||
|
return false;
|
||||||
|
}) ? csIpAddress.ToString() : processorIp;
|
||||||
|
|
||||||
|
var match = Regex.Match(url, @"^http://([^:/]+):\d+/mc/app\?token=.+$");
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
string ipa = match.Groups[1].Value;
|
||||||
|
// ip will be "192.168.1.100"
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace ipa with ip but leave the rest of the string intact
|
||||||
|
var updatedUrl = Regex.Replace(url, @"^http://[^:/]+", $"http://{ip}");
|
||||||
|
|
||||||
|
this.LogVerbose("Updated URL: {updatedUrl}", updatedUrl);
|
||||||
|
|
||||||
|
return updatedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
private void SubscribeForMobileControlUpdates()
|
private void SubscribeForMobileControlUpdates()
|
||||||
{
|
{
|
||||||
foreach (var dev in DeviceManager.AllDevices)
|
foreach (var dev in DeviceManager.AllDevices)
|
||||||
@@ -443,7 +519,8 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetAppUrl(string url)
|
public void SetAppUrl(string url)
|
||||||
{
|
{
|
||||||
_appUrl = url;
|
_appUrl = GetUrlWithCorrectIp(url);
|
||||||
|
|
||||||
AppUrlFeedback.FireUpdate();
|
AppUrlFeedback.FireUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
@@ -41,8 +42,14 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
|
|
||||||
private HttpServer _server;
|
private HttpServer _server;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the HttpServer instance
|
||||||
|
/// </summary>
|
||||||
public HttpServer Server => _server;
|
public HttpServer Server => _server;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the collection of UI client contexts
|
||||||
|
/// </summary>
|
||||||
public Dictionary<string, UiClientContext> UiClients { get; private set; }
|
public Dictionary<string, UiClientContext> UiClients { get; private set; }
|
||||||
|
|
||||||
private readonly MobileControlSystemController _parent;
|
private readonly MobileControlSystemController _parent;
|
||||||
@@ -61,17 +68,20 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string lanIpAddress => CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetLANAdapter));
|
private string LanIpAddress => CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetLANAdapter));
|
||||||
|
|
||||||
private System.Net.IPAddress csIpAddress;
|
private readonly System.Net.IPAddress csIpAddress;
|
||||||
|
|
||||||
private System.Net.IPAddress csSubnetMask;
|
private readonly System.Net.IPAddress csSubnetMask;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path for the WebSocket messaging
|
/// The path for the WebSocket messaging
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly string _wsPath = "/mc/api/ui/join/";
|
private readonly string _wsPath = "/mc/api/ui/join/";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the WebSocket path
|
||||||
|
/// </summary>
|
||||||
public string WsPath => _wsPath;
|
public string WsPath => _wsPath;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -89,6 +99,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int Port { get; private set; }
|
public int Port { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the user app URL prefix
|
||||||
|
/// </summary>
|
||||||
public string UserAppUrlPrefix
|
public string UserAppUrlPrefix
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -101,6 +114,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the count of connected UI clients
|
||||||
|
/// </summary>
|
||||||
public int ConnectedUiClientsCount
|
public int ConnectedUiClientsCount
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -119,6 +135,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the MobileControlWebsocketServer class.
|
||||||
|
/// </summary>
|
||||||
public MobileControlWebsocketServer(string key, int customPort, MobileControlSystemController parent)
|
public MobileControlWebsocketServer(string key, int customPort, MobileControlSystemController parent)
|
||||||
: base(key)
|
: base(key)
|
||||||
{
|
{
|
||||||
@@ -327,17 +346,26 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
string ip = processorIp;
|
string ip = processorIp;
|
||||||
if (touchpanel.Touchpanel is IMobileControlCrestronTouchpanelController crestronTouchpanel && csIpAddress != null)
|
|
||||||
|
// Moved to the MobileControlTouchpanelController class in the GetUrlWithCorrectIp method
|
||||||
|
// triggered by the Panel.IpInformationChange event so that we know we have the necessary info
|
||||||
|
// to make the determination of which IP to use.
|
||||||
|
//if (touchpanel.Touchpanel is IMobileControlCrestronTouchpanelController crestronTouchpanel && csIpAddress != null)
|
||||||
|
//{
|
||||||
|
// ip = crestronTouchpanel.ConnectedIps.Any(ipInfo =>
|
||||||
|
// {
|
||||||
|
// if (System.Net.IPAddress.TryParse(ipInfo.DeviceIpAddress, out var parsedIp))
|
||||||
|
// {
|
||||||
|
// return csIpAddress.IsInSameSubnet(parsedIp, csSubnetMask);
|
||||||
|
// }
|
||||||
|
// this.LogWarning("Invalid IP address: {deviceIpAddress}", ipInfo.DeviceIpAddress);
|
||||||
|
// return false;
|
||||||
|
// }) ? csIpAddress.ToString() : processorIp;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (_parent.Config.DirectServer.CSLanUiDeviceKeys != null && _parent.Config.DirectServer.CSLanUiDeviceKeys.Any(k => k.Equals(touchpanel.Touchpanel.Key, StringComparison.InvariantCultureIgnoreCase)) && csIpAddress != null)
|
||||||
{
|
{
|
||||||
ip = crestronTouchpanel.ConnectedIps.Any(ipInfo =>
|
ip = csIpAddress.ToString();
|
||||||
{
|
|
||||||
if (System.Net.IPAddress.TryParse(ipInfo.DeviceIpAddress, out var parsedIp))
|
|
||||||
{
|
|
||||||
return csIpAddress.IsInSameSubnet(parsedIp, csSubnetMask);
|
|
||||||
}
|
|
||||||
this.LogWarning("Invalid IP address: {deviceIpAddress}", ipInfo.DeviceIpAddress);
|
|
||||||
return false;
|
|
||||||
}) ? csIpAddress.ToString() : processorIp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var appUrl = $"http://{ip}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}";
|
var appUrl = $"http://{ip}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}";
|
||||||
@@ -621,6 +649,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
CrestronConsole.ConsoleCommandResponse($"Token: {token}");
|
CrestronConsole.ConsoleCommandResponse($"Token: {token}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validates the grant code against the room key
|
||||||
|
/// </summary>
|
||||||
public (string, string) ValidateGrantCode(string grantCode, string roomKey)
|
public (string, string) ValidateGrantCode(string grantCode, string roomKey)
|
||||||
{
|
{
|
||||||
var bridge = _parent.GetRoomBridge(roomKey);
|
var bridge = _parent.GetRoomBridge(roomKey);
|
||||||
@@ -634,6 +665,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
return ValidateGrantCode(grantCode, bridge);
|
return ValidateGrantCode(grantCode, bridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validates the grant code against the room key
|
||||||
|
/// </summary>
|
||||||
public (string, string) ValidateGrantCode(string grantCode, MobileControlBridgeBase bridge)
|
public (string, string) ValidateGrantCode(string grantCode, MobileControlBridgeBase bridge)
|
||||||
{
|
{
|
||||||
// TODO: Authenticate grant code passed in
|
// TODO: Authenticate grant code passed in
|
||||||
@@ -655,6 +689,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a new client token for the specified bridge
|
||||||
|
/// </summary>
|
||||||
public (string, string) GenerateClientToken(MobileControlBridgeBase bridge, string touchPanelKey = "")
|
public (string, string) GenerateClientToken(MobileControlBridgeBase bridge, string touchPanelKey = "")
|
||||||
{
|
{
|
||||||
var key = Guid.NewGuid().ToString();
|
var key = Guid.NewGuid().ToString();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
using System;
|
||||||
using System;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
@@ -41,29 +41,6 @@ namespace PepperDash.Essentials
|
|||||||
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
||||||
|
|
||||||
Debug.SetErrorLogMinimumDebugLevel(CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? LogEventLevel.Warning : LogEventLevel.Verbose);
|
Debug.SetErrorLogMinimumDebugLevel(CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? LogEventLevel.Warning : LogEventLevel.Verbose);
|
||||||
|
|
||||||
// AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args)
|
|
||||||
{
|
|
||||||
var assemblyName = new AssemblyName(args.Name).Name;
|
|
||||||
if (assemblyName == "PepperDash_Core")
|
|
||||||
{
|
|
||||||
return Assembly.LoadFrom("PepperDashCore.dll");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (assemblyName == "PepperDash_Essentials_Core")
|
|
||||||
{
|
|
||||||
return Assembly.LoadFrom("PepperDash.Essentials.Core.dll");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (assemblyName == "Essentials Devices Common")
|
|
||||||
{
|
|
||||||
return Assembly.LoadFrom("PepperDash.Essentials.Devices.Common.dll");
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -267,6 +244,8 @@ namespace PepperDash.Essentials
|
|||||||
// _ = new ProcessorExtensionDeviceFactory();
|
// _ = new ProcessorExtensionDeviceFactory();
|
||||||
// _ = new MobileControlFactory();
|
// _ = new MobileControlFactory();
|
||||||
|
|
||||||
|
LoadAssets();
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Starting Essentials load from configuration");
|
Debug.LogMessage(LogEventLevel.Information, "Starting Essentials load from configuration");
|
||||||
|
|
||||||
var filesReady = SetupFilesystem();
|
var filesReady = SetupFilesystem();
|
||||||
@@ -568,5 +547,142 @@ namespace PepperDash.Essentials
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void LoadAssets()
|
||||||
|
{
|
||||||
|
var applicationDirectory = new DirectoryInfo(Global.ApplicationDirectoryPathPrefix);
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "Searching: {applicationDirectory:l} for embedded assets - {Destination}", applicationDirectory.FullName, Global.FilePathPrefix);
|
||||||
|
|
||||||
|
var zipFiles = applicationDirectory.GetFiles("assets*.zip");
|
||||||
|
|
||||||
|
if (zipFiles.Length > 1)
|
||||||
|
{
|
||||||
|
throw new Exception("Multiple assets zip files found. Cannot continue.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zipFiles.Length == 1)
|
||||||
|
{
|
||||||
|
var zipFile = zipFiles[0];
|
||||||
|
var assetsRoot = System.IO.Path.GetFullPath(Global.FilePathPrefix);
|
||||||
|
if (!assetsRoot.EndsWith(Path.DirectorySeparatorChar.ToString()) && !assetsRoot.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||||
|
{
|
||||||
|
assetsRoot += Path.DirectorySeparatorChar;
|
||||||
|
}
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "Found assets zip file: {zipFile:l}... Unzipping...", zipFile.FullName);
|
||||||
|
using (var archive = ZipFile.OpenRead(zipFile.FullName))
|
||||||
|
{
|
||||||
|
foreach (var entry in archive.Entries)
|
||||||
|
{
|
||||||
|
var destinationPath = Path.Combine(Global.FilePathPrefix, entry.FullName);
|
||||||
|
var fullDest = System.IO.Path.GetFullPath(destinationPath);
|
||||||
|
if (!fullDest.StartsWith(assetsRoot, StringComparison.OrdinalIgnoreCase))
|
||||||
|
throw new InvalidOperationException($"Entry '{entry.FullName}' is trying to extract outside of the target directory.");
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(entry.Name))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(destinationPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a directory exists where a file should go, delete it
|
||||||
|
if (Directory.Exists(destinationPath))
|
||||||
|
Directory.Delete(destinationPath, true);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(destinationPath));
|
||||||
|
entry.ExtractToFile(destinationPath, true);
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "Extracted: {entry:l} to {Destination}", entry.FullName, destinationPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleaning up zip files
|
||||||
|
foreach (var file in zipFiles)
|
||||||
|
{
|
||||||
|
File.Delete(file.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
var htmlZipFiles = applicationDirectory.GetFiles("htmlassets*.zip");
|
||||||
|
|
||||||
|
if (htmlZipFiles.Length > 1)
|
||||||
|
{
|
||||||
|
throw new Exception("Multiple htmlassets zip files found in application directory. Please ensure only one htmlassets*.zip file is present and retry.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (htmlZipFiles.Length == 1)
|
||||||
|
{
|
||||||
|
var htmlZipFile = htmlZipFiles[0];
|
||||||
|
var programDir = new DirectoryInfo(Global.FilePathPrefix.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
|
||||||
|
var userOrNvramDir = programDir.Parent;
|
||||||
|
var rootDir = userOrNvramDir?.Parent;
|
||||||
|
if (rootDir == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Unable to determine root directory for html extraction. Current path: {Global.FilePathPrefix}");
|
||||||
|
}
|
||||||
|
var htmlDir = Path.Combine(rootDir.FullName, "html");
|
||||||
|
var htmlRoot = System.IO.Path.GetFullPath(htmlDir);
|
||||||
|
if (!htmlRoot.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
|
||||||
|
!htmlRoot.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||||
|
{
|
||||||
|
htmlRoot += Path.DirectorySeparatorChar;
|
||||||
|
}
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "Found htmlassets zip file: {zipFile:l}... Unzipping...", htmlZipFile.FullName);
|
||||||
|
using (var archive = ZipFile.OpenRead(htmlZipFile.FullName))
|
||||||
|
{
|
||||||
|
foreach (var entry in archive.Entries)
|
||||||
|
{
|
||||||
|
var destinationPath = Path.Combine(htmlDir, entry.FullName);
|
||||||
|
var fullDest = System.IO.Path.GetFullPath(destinationPath);
|
||||||
|
if (!fullDest.StartsWith(htmlRoot, StringComparison.OrdinalIgnoreCase))
|
||||||
|
throw new InvalidOperationException($"Entry '{entry.FullName}' is trying to extract outside of the target directory.");
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(entry.Name))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(destinationPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only delete the file if it exists and is a file, not a directory
|
||||||
|
if (File.Exists(destinationPath))
|
||||||
|
File.Delete(destinationPath);
|
||||||
|
|
||||||
|
var parentDir = Path.GetDirectoryName(destinationPath);
|
||||||
|
if (!string.IsNullOrEmpty(parentDir))
|
||||||
|
Directory.CreateDirectory(parentDir);
|
||||||
|
|
||||||
|
entry.ExtractToFile(destinationPath, true);
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "Extracted: {entry:l} to {Destination}", entry.FullName, destinationPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleaning up html zip files
|
||||||
|
foreach (var file in htmlZipFiles)
|
||||||
|
{
|
||||||
|
File.Delete(file.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonFiles = applicationDirectory.GetFiles("*configurationFile*.json");
|
||||||
|
|
||||||
|
if (jsonFiles.Length > 1)
|
||||||
|
{
|
||||||
|
throw new Exception("Multiple configuration files found. Cannot continue.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonFiles.Length == 1)
|
||||||
|
{
|
||||||
|
var jsonFile = jsonFiles[0];
|
||||||
|
var finalPath = Path.Combine(Global.FilePathPrefix, jsonFile.Name);
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "Found configuration file: {jsonFile:l}... Moving to: {Destination}", jsonFile.FullName, finalPath);
|
||||||
|
|
||||||
|
if (File.Exists(finalPath))
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "Removing existing configuration file: {Destination}", finalPath);
|
||||||
|
File.Delete(finalPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonFile.MoveTo(finalPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Crestron.SimplSharp.SDK.Program" Version="2.21.90" />
|
<PackageReference Include="Crestron.SimplSharp.SDK.Program" Version="2.21.90" />
|
||||||
|
<PackageReference Include="System.IO.Compression" Version="4.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\PepperDash.Core\PepperDash.Core.csproj" />
|
<ProjectReference Include="..\PepperDash.Core\PepperDash.Core.csproj" />
|
||||||
|
|||||||
Reference in New Issue
Block a user