Compare commits

..

3 Commits

Author SHA1 Message Date
Neil Dorin
9de94bd65f fix: Update v2 config detection criteria
Changed the logic for identifying v2 configuration files. The check now looks for the presence of a "versions" node instead of the absence of "system" or "template" nodes, reflecting an update in the configuration file structure.
2025-09-22 15:05:06 -06:00
Neil Dorin
ff46fb8f29 feat: Add versioning support to EssentialsConfig
Introduce `Versions` property in `EssentialsConfig` to hold version information.
Add `VersionData` class for Essentials and package versions, and `NugetVersion` class for individual package details.
Retain and document `SystemTemplateConfigs` class.
2025-09-22 14:55:58 -06:00
Neil Dorin
d9243def30 feat: Adds ability to read configs generated from v2 config tool that are pre-merged don't have system or template objects
Refactor config handling and improve documentation

- Updated `PortalConfigReader.cs` to use constants for configuration keys, enhancing maintainability and readability. Improved error logging with `Debug.LogError`.
- Modified `ConfigReader.cs` to handle v2 configuration format, streamlining the loading process and avoiding redundant parsing.
- Added XML documentation comments to properties in `EssentialsConfig.cs`, improving code documentation. Initialized `Rooms` property in the constructor.
- Enhanced `SystemTemplateConfigs` class with XML documentation for better clarity on its properties.
2025-09-22 14:22:57 -06:00
103 changed files with 1773 additions and 2852 deletions

View File

@@ -23,32 +23,23 @@
<FileName>$(TargetDir)$(TargetName).$(Version).$(TargetFramework).cpz</FileName>
</PropertyGroup>
<Target Name="DeleteCLZ" BeforeTargets="CoreBuild" Condition="$(ProjectType) == 'Library' And $(TargetDir) != ''">
<ItemGroup>
<OldCLZFiles Include="$(TargetDir)$(TargetName).*.$(TargetFramework).clz" />
</ItemGroup>
<Delete Files="@(OldCLZFiles)" Condition="@(OldCLZFiles) != ''">
<Target Name="DeleteCLZ" BeforeTargets="PreBuildEvent" Condition="$(ProjectType) == 'Library' And $(TargetDir) != '' And Exists($(FileName))">
<Delete Files="$(TargetDir)$(TargetName).$(Version).$(TargetFramework).clz">
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
</Delete>
<Message Text="Deleted old CLZ files: '@(DeletedList)'" Condition="@(DeletedList) != ''" />
<Message Text="Deleted files: '@(DeletedList)'" />
</Target>
<Target Name="DeleteCPZ" BeforeTargets="CoreBuild" Condition="$(ProjectType) == 'Program' And $(TargetDir) != ''">
<ItemGroup>
<OldCPZFiles Include="$(TargetDir)$(TargetName).*.$(TargetFramework).cpz" />
</ItemGroup>
<Delete Files="@(OldCPZFiles)" Condition="@(OldCPZFiles) != ''">
<Target Name="DeleteCPZ" BeforeTargets="PreBuildEvent" Condition="$(ProjectType) == 'Program' And $(TargetDir) != '' And Exists($(FileName))">
<Delete Files="$(TargetDir)$(TargetName).$(Version).$(TargetFramework).cpz">
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
</Delete>
<Message Text="Deleted old CPZ files: '@(DeletedList)'" Condition="@(DeletedList) != ''" />
<Message Text="Deleted files: '@(DeletedList)'" />
</Target>
<Target Name="DeleteCPLZ" BeforeTargets="CoreBuild" Condition="$(ProjectType) == 'ProgramLibrary' And $(TargetDir) != ''">
<ItemGroup>
<OldCPLZFiles Include="$(TargetDir)$(TargetName).*.$(TargetFramework).cplz" />
</ItemGroup>
<Delete Files="@(OldCPLZFiles)" Condition="@(OldCPLZFiles) != ''">
<Target Name="DeleteCPLZ" BeforeTargets="PreBuildEvent" Condition="$(ProjectType) == 'ProgramLibrary' And $(TargetDir) != '' And Exists($(FileName))">
<Delete Files="$(TargetDir)$(TargetName).$(Version).$(TargetFramework).cplz">
<Output TaskParameter="DeletedFiles" ItemName="DeletedList"/>
</Delete>
<Message Text="Deleted old CPLZ files: '@(DeletedList)'" Condition="@(DeletedList) != ''" />
<Message Text="Deleted files: '@(DeletedList)'" />
</Target>
<Target Name="CreateCPLZ" AfterTargets="Build" Condition="$(ProjectType) == 'ProgramLibrary' And $(TargetDir) != ''" DependsOnTargets="DeleteCPLZ">

View File

@@ -131,14 +131,14 @@ namespace PepperDash.Core
/// <param name="key"></param>
/// <param name="address"></param>
/// <param name="port"></param>
/// <param name="bufferSize"></param>
public GenericUdpServer(string key, string address, int port, int bufferSize)
/// <param name="buffefSize"></param>
public GenericUdpServer(string key, string address, int port, int buffefSize)
: base(key)
{
StreamDebugging = new CommunicationStreamDebugging(key);
Hostname = address;
Port = port;
BufferSize = bufferSize;
BufferSize = buffefSize;
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
@@ -194,21 +194,7 @@ namespace PepperDash.Core
{
if (Server == null)
{
try
{
var address = IPAddress.Parse(Hostname);
Server = new UDPServer(address, Port, BufferSize);
}
catch (Exception ex)
{
this.LogError("Error parsing IP Address '{ipAddress}': message: {message}", Hostname, ex.Message);
this.LogInformation("Creating UDPServer with default buffersize");
Server = new UDPServer();
}
Server = new UDPServer();
}
if (string.IsNullOrEmpty(Hostname))

View File

@@ -9,40 +9,59 @@ using Serilog.Events;
namespace PepperDash.Core.Config
{
/// <summary>
/// Reads a Portal formatted config file
/// </summary>
public class PortalConfigReader
{
/// <summary>
/// Reads the config file, checks if it needs a merge, merges and saves, then returns the merged Object.
/// </summary>
/// <returns>JObject of config file</returns>
public static void ReadAndMergeFileIfNecessary(string filePath, string savePath)
const string template = "template";
const string system = "system";
const string systemUrl = "system_url";
const string templateUrl = "template_url";
const string info = "info";
const string devices = "devices";
const string rooms = "rooms";
const string sourceLists = "sourceLists";
const string destinationLists = "destinationLists";
const string cameraLists = "cameraLists";
const string audioControlPointLists = "audioControlPointLists";
const string tieLines = "tieLines";
const string joinMaps = "joinMaps";
const string global = "global";
/// <summary>
/// Reads the config file, checks if it needs a merge, merges and saves, then returns the merged Object.
/// </summary>
/// <returns>JObject of config file</returns>
public static void ReadAndMergeFileIfNecessary(string filePath, string savePath)
{
try
{
if (!File.Exists(filePath))
{
Debug.Console(1, Debug.ErrorLogLevel.Error,
Debug.LogError(
"ERROR: Configuration file not present. Please load file to {0} and reset program", filePath);
}
using (StreamReader fs = new StreamReader(filePath))
{
var jsonObj = JObject.Parse(fs.ReadToEnd());
if(jsonObj["template"] != null && jsonObj["system"] != null)
if(jsonObj[template] != null && jsonObj[system] != null)
{
// it's a double-config, merge it.
var merged = MergeConfigs(jsonObj);
if (jsonObj["system_url"] != null)
if (jsonObj[systemUrl] != null)
{
merged["systemUrl"] = jsonObj["system_url"].Value<string>();
merged[systemUrl] = jsonObj[systemUrl].Value<string>();
}
if (jsonObj["template_url"] != null)
if (jsonObj[templateUrl] != null)
{
merged["templateUrl"] = jsonObj["template_url"].Value<string>();
merged[templateUrl] = jsonObj[templateUrl].Value<string>();
}
jsonObj = merged;
@@ -77,62 +96,62 @@ namespace PepperDash.Core.Config
var merged = new JObject();
// Put together top-level objects
if (system["info"] != null)
merged.Add("info", Merge(template["info"], system["info"], "infO"));
if (system[info] != null)
merged.Add(info, Merge(template[info], system[info], info));
else
merged.Add("info", template["info"]);
merged.Add(info, template[info]);
merged.Add("devices", MergeArraysOnTopLevelProperty(template["devices"] as JArray,
system["devices"] as JArray, "key", "devices"));
merged.Add(devices, MergeArraysOnTopLevelProperty(template[devices] as JArray,
system[devices] as JArray, "key", devices));
if (system["rooms"] == null)
merged.Add("rooms", template["rooms"]);
if (system[rooms] == null)
merged.Add(rooms, template[rooms]);
else
merged.Add("rooms", MergeArraysOnTopLevelProperty(template["rooms"] as JArray,
system["rooms"] as JArray, "key", "rooms"));
merged.Add(rooms, MergeArraysOnTopLevelProperty(template[rooms] as JArray,
system[rooms] as JArray, "key", rooms));
if (system["sourceLists"] == null)
merged.Add("sourceLists", template["sourceLists"]);
if (system[sourceLists] == null)
merged.Add(sourceLists, template[sourceLists]);
else
merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"], "sourceLists"));
merged.Add(sourceLists, Merge(template[sourceLists], system[sourceLists], sourceLists));
if (system["destinationLists"] == null)
merged.Add("destinationLists", template["destinationLists"]);
if (system[destinationLists] == null)
merged.Add(destinationLists, template[destinationLists]);
else
merged.Add("destinationLists",
Merge(template["destinationLists"], system["destinationLists"], "destinationLists"));
merged.Add(destinationLists,
Merge(template[destinationLists], system[destinationLists], destinationLists));
if (system["cameraLists"] == null)
merged.Add("cameraLists", template["cameraLists"]);
if (system[cameraLists] == null)
merged.Add(cameraLists, template[cameraLists]);
else
merged.Add("cameraLists", Merge(template["cameraLists"], system["cameraLists"], "cameraLists"));
merged.Add(cameraLists, Merge(template[cameraLists], system[cameraLists], cameraLists));
if (system["audioControlPointLists"] == null)
merged.Add("audioControlPointLists", template["audioControlPointLists"]);
if (system[audioControlPointLists] == null)
merged.Add(audioControlPointLists, template[audioControlPointLists]);
else
merged.Add("audioControlPointLists",
Merge(template["audioControlPointLists"], system["audioControlPointLists"], "audioControlPointLists"));
merged.Add(audioControlPointLists,
Merge(template[audioControlPointLists], system[audioControlPointLists], audioControlPointLists));
// Template tie lines take precedence. Config tool doesn't do them at system
// level anyway...
if (template["tieLines"] != null)
merged.Add("tieLines", template["tieLines"]);
else if (system["tieLines"] != null)
merged.Add("tieLines", system["tieLines"]);
if (template[tieLines] != null)
merged.Add(tieLines, template[tieLines]);
else if (system[tieLines] != null)
merged.Add(tieLines, system[tieLines]);
else
merged.Add("tieLines", new JArray());
merged.Add(tieLines, new JArray());
if (template["joinMaps"] != null)
merged.Add("joinMaps", template["joinMaps"]);
if (template[joinMaps] != null)
merged.Add(joinMaps, template[joinMaps]);
else
merged.Add("joinMaps", new JObject());
merged.Add(joinMaps, new JObject());
if (system["global"] != null)
merged.Add("global", Merge(template["global"], system["global"], "global"));
if (system[global] != null)
merged.Add(global, Merge(template[global], system[global], global));
else
merged.Add("global", template["global"]);
merged.Add(global, template[global]);
//Debug.Console(2, "MERGED CONFIG RESULT: \x0d\x0a{0}", merged);
return merged;
@@ -228,7 +247,7 @@ namespace PepperDash.Core.Config
}
catch (Exception e)
{
Debug.Console(1, Debug.ErrorLogLevel.Warning, "Cannot merge items at path {0}: \r{1}", propPath, e);
Debug.LogError("Cannot merge items at path {propPath}: \r{e}", propPath, e);
}
}
}

View File

@@ -124,22 +124,35 @@ namespace PepperDash.Essentials.Core.Config
Debug.LogMessage(LogEventLevel.Information, "Successfully Loaded Local Config");
return true;
}
}
else
{
var doubleObj = JObject.Parse(fs.ReadToEnd());
ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
var parsedConfig = JObject.Parse(fs.ReadToEnd());
// Extract SystemUrl and TemplateUrl into final config output
if (doubleObj["system_url"] != null)
// Check if it's a v2 config (check for "version" node)
// this means it's already merged by the Portal API
// from the v2 config tool
var isV2Config = parsedConfig["versions"] != null;
if (isV2Config)
{
ConfigObject.SystemUrl = doubleObj["system_url"].Value<string>();
Debug.LogMessage(LogEventLevel.Information, "Config file is a v2 format, no merge necessary.");
ConfigObject = parsedConfig.ToObject<EssentialsConfig>();
Debug.LogMessage(LogEventLevel.Information, "Successfully Loaded v2 Config");
return true;
}
if (doubleObj["template_url"] != null)
// Extract SystemUrl and TemplateUrl into final config output
ConfigObject = PortalConfigReader.MergeConfigs(parsedConfig).ToObject<EssentialsConfig>();
if (parsedConfig["system_url"] != null)
{
ConfigObject.TemplateUrl = doubleObj["template_url"].Value<string>();
ConfigObject.SystemUrl = parsedConfig["system_url"].Value<string>();
}
if (parsedConfig["template_url"] != null)
{
ConfigObject.TemplateUrl = parsedConfig["template_url"].Value<string>();
}
}

View File

@@ -16,13 +16,21 @@ namespace PepperDash.Essentials.Core.Config
/// </summary>
public class EssentialsConfig : BasicConfig
{
[JsonProperty("system_url")]
/// <summary>
/// Gets or sets the SystemUrl
/// </summary>
[JsonProperty("system_url")]
public string SystemUrl { get; set; }
[JsonProperty("template_url")]
/// <summary>
/// Gets or sets the TemplateUrl
/// </summary>
[JsonProperty("template_url")]
public string TemplateUrl { get; set; }
/// <summary>
/// Gets the SystemUuid extracted from the SystemUrl
/// </summary>
[JsonProperty("systemUuid")]
public string SystemUuid
{
@@ -45,6 +53,9 @@ namespace PepperDash.Essentials.Core.Config
}
}
/// <summary>
/// Gets the TemplateUuid extracted from the TemplateUrl
/// </summary>
[JsonProperty("templateUuid")]
public string TemplateUuid
{
@@ -67,30 +78,85 @@ namespace PepperDash.Essentials.Core.Config
}
}
[JsonProperty("rooms")]
/// <summary>
/// Gets or sets the Rooms
/// </summary>
[JsonProperty("rooms")]
public List<DeviceConfig> Rooms { get; set; }
/// <summary>
/// Gets or sets the Versions
/// </summary>
public VersionData Versions { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="EssentialsConfig"/> class.
/// </summary>
public EssentialsConfig()
: base()
{
Rooms = new List<DeviceConfig>();
}
}
/// <summary>
/// Represents a SystemTemplateConfigs
/// </summary>
public class SystemTemplateConfigs
/// <summary>
/// Represents version data for Essentials and its packages
/// </summary>
public class VersionData
{
/// <summary>
/// Gets or sets the Essentials version
/// </summary>
[JsonProperty("essentials")]
public NugetVersion Essentials { get; set; }
/// <summary>
/// Gets or sets the list of Packages
/// </summary>
[JsonProperty("packages")]
public List<NugetVersion> Packages { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="VersionData"/> class.
/// </summary>
public VersionData()
{
Packages = new List<NugetVersion>();
}
}
/// <summary>
/// Represents a NugetVersion
/// </summary>
public class NugetVersion
{
/// <summary>
/// Gets or sets the Version
/// </summary>
[JsonProperty("version")]
public string Version { get; set; }
/// <summary>
/// Gets or sets the PackageId
/// </summary>
[JsonProperty("packageId")]
public string PackageId { get; set; }
}
/// <summary>
/// Represents a SystemTemplateConfigs
/// </summary>
public class SystemTemplateConfigs
{
/// <summary>
/// Gets or sets the System
/// </summary>
/// <summary>
/// Gets or sets the System
/// </summary>
public EssentialsConfig System { get; set; }
/// <summary>
/// Gets or sets the Template
/// </summary>
public EssentialsConfig Template { get; set; }
}
}

View File

@@ -2,54 +2,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Core.CrestronIO
{
[Description("Wrapper class for Digital Input")]
/// <summary>
/// Represents a GenericDigitalInputDevice
/// </summary>
/// [Description("Wrapper class for Digital Input")]
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IHasFeedback
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
{
private DigitalInput inputPort;
/// <summary>
/// Gets or sets the InputPort
/// </summary>
public DigitalInput InputPort { get; private set; }
/// <summary>
/// Gets or sets the InputStateFeedback
/// </summary>
public BoolFeedback InputStateFeedback { get; private set; }
/// <inheritdoc />
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
Func<bool> InputStateFeedbackFunc
{
get
{
return () => InputPort.State;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="GenericDigitalInputDevice"/> class.
/// </summary>
/// <param name="key">key for device</param>
/// <param name="name">name for device</param>
/// <param name="postActivationFunc">function to call after activation. Should return the DigitalInput</param>
/// <param name="config">config for device</param>
public GenericDigitalInputDevice(string key, string name, Func<IOPortConfig, DigitalInput> postActivationFunc,
IOPortConfig config)
: base(key, name)
{
InputStateFeedback = new BoolFeedback("inputState", () => inputPort.State);
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
AddPostActivationAction(() =>
{
inputPort = postActivationFunc(config);
InputPort = postActivationFunc(config);
inputPort.Register();
InputPort.Register();
InputPort.StateChange += InputPort_StateChange;
inputPort.StateChange += InputPort_StateChange;
});
}
@@ -66,31 +71,41 @@ namespace PepperDash.Essentials.Core.CrestronIO
private static DigitalInput GetDigitalInput(IOPortConfig dc)
{
IDigitalInputPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor"))
{
if (!Global.ControlSystem.SupportsDigitalInput)
{
Debug.LogError("GetDigitalInput: Processor does not support Digital Inputs");
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Processor does not support Digital Inputs");
return null;
}
return Global.ControlSystem.DigitalInputPorts[dc.PortNumber];
ioPortDevice = Global.ControlSystem;
}
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IDigitalInputPorts ioPortDevice))
else
{
Debug.LogError("GetDigitalInput: Device {key} is not a valid device", dc.PortDeviceKey);
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IDigitalInputPorts;
if (ioPortDev == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device '0' is not a valid IDigitalInputPorts Device", dc.PortDeviceKey);
return null;
}
if (dc.PortNumber > ioPortDevice.NumberOfDigitalInputPorts)
{
Debug.LogError("GetDigitalInput: Device {key} does not contain a digital input port {port}", dc.PortDeviceKey, dc.PortNumber);
return null;
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
}
return ioPortDevice.DigitalInputPorts[dc.PortNumber];
}
#endregion
@@ -116,20 +131,20 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
else
{
this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
try
{
this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
}
catch (Exception e)
{
this.LogError("Unable to link device {key}. {message}", Key, e.Message);
this.LogDebug(e, "Stack Trace: ");
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
}
}
@@ -138,22 +153,22 @@ namespace PepperDash.Essentials.Core.CrestronIO
#region Factory
/// <summary>
/// Factory for creating GenericDigitalInputDevice devices
/// Represents a GenericDigitalInputDeviceFactory
/// </summary>
public class GenericDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericDigitalInputDevice>
{
/// <summary>
/// Constructor for GenericDigitalInputDeviceFactory
/// </summary>
public GenericDigitalInputDeviceFactory()
{
TypeNames = new List<string>() { "digitalinput" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogDebug("Factory Attempting to create new Generic Digital Input Device");
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Digital Input Device");
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());

View File

@@ -2,64 +2,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json;
using Serilog.Events;
namespace PepperDash.Essentials.Core.CrestronIO
{
/// <summary>
/// Represents a generic digital input deviced tied to a versiport
/// </summary>
public class GenericVersiportAnalogInputDevice : EssentialsBridgeableDevice, IAnalogInput, IHasFeedback
public class GenericVersiportAnalogInputDevice : EssentialsBridgeableDevice, IAnalogInput
{
private Versiport inputPort;
public Versiport InputPort { get; private set; }
/// <inheritdoc />
public IntFeedback InputValueFeedback { get; private set; }
/// <summary>
/// Get the InputMinimumChangeFeedback
/// </summary>
/// <remarks>
/// Updates when the analog input minimum change value changes
/// </remarks>
public IntFeedback InputMinimumChangeFeedback { get; private set; }
/// <inheritdoc />
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
Func<int> InputValueFeedbackFunc
{
get
{
return () => InputPort.AnalogIn;
}
}
Func<int> InputMinimumChangeFeedbackFunc
{
get { return () => InputPort.AnalogMinChange; }
}
/// <summary>
/// Initializes a new instance of the <see cref="GenericVersiportAnalogInputDevice"/> class.
/// </summary>
/// <param name="key">key for the device</param>
/// <param name="name">name for the device</param>
/// <param name="postActivationFunc">function to call after activation</param>
/// <param name="config">IO port configuration</param>
public GenericVersiportAnalogInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name)
{
InputValueFeedback = new IntFeedback("inputValue", () => inputPort.AnalogIn);
InputMinimumChangeFeedback = new IntFeedback("inputMinimumChange", () => inputPort.AnalogMinChange);
InputValueFeedback = new IntFeedback(InputValueFeedbackFunc);
InputMinimumChangeFeedback = new IntFeedback(InputMinimumChangeFeedbackFunc);
AddPostActivationAction(() =>
{
inputPort = postActivationFunc(config);
InputPort = postActivationFunc(config);
inputPort.Register();
InputPort.Register();
inputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput);
inputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655);
InputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput);
InputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655);
if (config.DisablePullUpResistor)
inputPort.DisablePullUpResistor = true;
InputPort.DisablePullUpResistor = true;
inputPort.VersiportChange += InputPort_VersiportChange;
InputPort.VersiportChange += InputPort_VersiportChange;
Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportAnalogInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
this.LogDebug("Created GenericVersiportAnalogInputDevice on port {port}. DisablePullUpResistor: {pullUpResistorDisabled}", config.PortNumber, inputPort.DisablePullUpResistor);
});
}
@@ -67,17 +69,20 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// <summary>
/// Set minimum voltage change for device to update voltage changed method
/// </summary>
/// <param name="value">valid values range from 0 - 65535, representing the full 100% range of the processor voltage source. Check processor documentation for details</param>
/// <param name="value">valid values range from 0 - 65535, representing the full 100% range of the processor voltage source. Check processor documentation for details</param>
/// <summary>
/// SetMinimumChange method
/// </summary>
public void SetMinimumChange(ushort value)
{
inputPort.AnalogMinChange = value;
InputPort.AnalogMinChange = value;
}
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
{
this.LogDebug("Versiport change: {event}", args.Event);
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event);
if (args.Event == eVersiportEvent.AnalogInChange)
if(args.Event == eVersiportEvent.AnalogInChange)
InputValueFeedback.FireUpdate();
if (args.Event == eVersiportEvent.AnalogMinChangeChange)
InputMinimumChangeFeedback.FireUpdate();
@@ -86,6 +91,9 @@ namespace PepperDash.Essentials.Core.CrestronIO
#region Bridge Linking
/// <summary>
/// LinkToApi method
/// </summary>
/// <inheritdoc />
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
@@ -102,12 +110,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
else
{
this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
try
{
this.LogDebug("Linking to Trilist '{trilistId}'", trilist.ID.ToString("X"));
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state
InputValueFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputValue.JoinNumber]);
@@ -117,8 +125,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
catch (Exception e)
{
this.LogError("Unable to link device {key}: {message}", Key, e.Message);
this.LogDebug(e, "Stack Trace: ");
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
}
trilist.OnlineStatusChange += (d, args) =>
@@ -130,6 +138,11 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
void trilist_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
throw new NotImplementedException();
}
#endregion
@@ -138,55 +151,70 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary>
public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
{
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor"))
{
if (!Global.ControlSystem.SupportsVersiport)
{
Debug.LogError("GetVersiportAnalogInput: Processor does not support Versiports");
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Processor does not support Versiports");
return null;
}
return Global.ControlSystem.VersiPorts[dc.PortNumber];
ioPortDevice = Global.ControlSystem;
}
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
else
{
Debug.LogError("GetVersiportAnalogInput: Device {key} is not a valid device", dc.PortDeviceKey);
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
if (ioPortDev == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
return null;
}
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{
Debug.LogError("GetVersiportAnalogInput: Device {key} does not contain a port {port}", dc.PortDeviceKey, dc.PortNumber);
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
return null;
}
if (!ioPortDevice.VersiPorts[dc.PortNumber].SupportsAnalogInput)
if(!ioPortDevice.VersiPorts[dc.PortNumber].SupportsAnalogInput)
{
Debug.LogError("GetVersiportAnalogInput: Device {key} does not support AnalogInput on port {port}", dc.PortDeviceKey, dc.PortNumber);
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} does not support AnalogInput on port {1}", dc.PortDeviceKey, dc.PortNumber);
return null;
}
return ioPortDevice.VersiPorts[dc.PortNumber];
}
}
/// <summary>
/// Factory for creating GenericVersiportAnalogInputDevice devices
/// Represents a GenericVersiportAbalogInputDeviceFactory
/// </summary>
public class GenericVersiportAnalogInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportAnalogInputDevice>
public class GenericVersiportAbalogInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportAnalogInputDevice>
{
/// <summary>
/// Constructor for GenericVersiportAnalogInputDeviceFactory
/// </summary>
public GenericVersiportAnalogInputDeviceFactory()
public GenericVersiportAbalogInputDeviceFactory()
{
TypeNames = new List<string>() { "versiportanaloginput" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogDebug("Factory Attempting to create new Generic Versiport Device");
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device");
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());

View File

@@ -2,82 +2,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json;
using Serilog.Events;
namespace PepperDash.Essentials.Core.CrestronIO
{
/// <summary>
/// Represents a generic digital input deviced tied to a versiport
/// </summary>
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider, IHasFeedback
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider
{
private Versiport inputPort;
public Versiport InputPort { get; private set; }
/// <summary>
/// Gets or sets the InputStateFeedback
/// </summary>
public BoolFeedback InputStateFeedback { get; private set; }
/// <inheritdoc />
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
Func<bool> InputStateFeedbackFunc
{
get
{
return () => InputPort.DigitalIn;
}
}
/// <summary>
/// Gets or sets the PartitionPresentFeedback
/// </summary>
public BoolFeedback PartitionPresentFeedback { get; }
/// <summary>
/// Get partition state
/// </summary>
public bool PartitionPresent => !inputPort.DigitalIn;
public bool PartitionPresent => !InputStateFeedbackFunc();
/// <summary>
/// Initializes a new instance of the <see cref="GenericVersiportDigitalInputDevice"/> class.
/// </summary>
/// <param name="key">key for device</param>
/// <param name="name">name for device</param>
/// <param name="postActivationFunc">function to call after activation. Should return the Versiport</param>
/// <param name="config">config for device</param>
public GenericVersiportDigitalInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name)
{
InputStateFeedback = new BoolFeedback("inputState", () => inputPort.DigitalIn);
PartitionPresentFeedback = new BoolFeedback("partitionPresent", () => !inputPort.DigitalIn);
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
PartitionPresentFeedback = new BoolFeedback(() => !InputStateFeedbackFunc());
AddPostActivationAction(() =>
{
inputPort = postActivationFunc(config);
InputPort = postActivationFunc(config);
inputPort.Register();
InputPort.Register();
inputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
if (config.DisablePullUpResistor)
inputPort.DisablePullUpResistor = true;
InputPort.DisablePullUpResistor = true;
inputPort.VersiportChange += InputPort_VersiportChange;
InputPort.VersiportChange += InputPort_VersiportChange;
InputStateFeedback.FireUpdate();
PartitionPresentFeedback.FireUpdate();
this.LogDebug("Created GenericVersiportDigitalInputDevice for port {port}. DisablePullUpResistor: {pullUpResistorDisable}", config.PortNumber, inputPort.DisablePullUpResistor);
Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
});
Feedbacks.Add(InputStateFeedback);
Feedbacks.Add(PartitionPresentFeedback);
}
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
{
this.LogDebug("Versiport change: {0}", args.Event);
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event);
if (args.Event == eVersiportEvent.DigitalInChange)
if(args.Event == eVersiportEvent.DigitalInChange)
{
InputStateFeedback.FireUpdate();
PartitionPresentFeedback.FireUpdate();
@@ -106,20 +102,20 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
else
{
this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
try
{
this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
}
catch (Exception e)
{
this.LogError("Unable to link device {key}. Input is null. {message}", Key, e.Message);
this.LogDebug(e, "Stack Trace: ");
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
}
}
@@ -131,50 +127,63 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary>
public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
{
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor"))
{
if (!Global.ControlSystem.SupportsVersiport)
{
Debug.LogError("GetVersiportDigitalInput: Processor does not support Versiports");
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Processor does not support Versiports");
return null;
}
return Global.ControlSystem.VersiPorts[dc.PortNumber];
ioPortDevice = Global.ControlSystem;
}
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
else
{
Debug.LogError("GetVersiportDigitalInput: Device {key} is not a valid device", dc.PortDeviceKey);
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
if (ioPortDev == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
return null;
}
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{
Debug.LogError("GetVersiportDigitalInput: Device {key} does not contain versiport {port}", dc.PortDeviceKey, dc.PortNumber);
return null;
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
}
return ioPortDevice.VersiPorts[dc.PortNumber];
}
}
/// <summary>
/// Factory class for GenericVersiportDigitalInputDevice
/// Represents a GenericVersiportDigitalInputDeviceFactory
/// </summary>
public class GenericVersiportDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
{
/// <summary>
/// Constructor for GenericVersiportDigitalInputDeviceFactory
/// </summary>
public GenericVersiportDigitalInputDeviceFactory()
{
TypeNames = new List<string>() { "versiportinput" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogDebug("Factory Attempting to create new Generic Versiport Device");
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device");
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());

View File

@@ -2,13 +2,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json;
using Serilog.Events;
namespace PepperDash.Essentials.Core.CrestronIO
@@ -16,68 +21,76 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// <summary>
/// Represents a generic digital input deviced tied to a versiport
/// </summary>
public class GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput, IHasFeedback
public class GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput
{
private Versiport outputPort;
public Versiport OutputPort { get; private set; }
/// <summary>
/// Gets or sets the OutputStateFeedback
/// </summary>
public BoolFeedback OutputStateFeedback { get; private set; }
/// <inheritdoc />
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
Func<bool> OutputStateFeedbackFunc
{
get
{
return () => OutputPort.DigitalOut;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="GenericVersiportDigitalOutputDevice"/> class.
/// </summary>
public GenericVersiportDigitalOutputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name)
{
OutputStateFeedback = new BoolFeedback("outputState", () => outputPort.DigitalOut);
OutputStateFeedback = new BoolFeedback(OutputStateFeedbackFunc);
AddPostActivationAction(() =>
{
outputPort = postActivationFunc(config);
OutputPort = postActivationFunc(config);
outputPort.Register();
OutputPort.Register();
if (!outputPort.SupportsDigitalOutput)
if (!OutputPort.SupportsDigitalOutput)
{
this.LogError("Device does not support configuration as a Digital Output");
Debug.LogMessage(LogEventLevel.Information, this, "Device does not support configuration as a Digital Output");
return;
}
outputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput);
OutputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput);
outputPort.VersiportChange += OutputPort_VersiportChange;
OutputPort.VersiportChange += OutputPort_VersiportChange;
});
}
void OutputPort_VersiportChange(Versiport port, VersiportEventArgs args)
{
this.LogDebug("Versiport change: {event}", args.Event);
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event);
if (args.Event == eVersiportEvent.DigitalOutChange)
if(args.Event == eVersiportEvent.DigitalOutChange)
OutputStateFeedback.FireUpdate();
}
/// <summary>
/// Set value of the versiport digital output
/// </summary>
/// <param name="state">value to set the output to</param>
/// <param name="state">value to set the output to</param>
/// <summary>
/// SetOutput method
/// </summary>
public void SetOutput(bool state)
{
if (!outputPort.SupportsDigitalOutput)
{
this.LogError("Versiport does not support Digital Output Mode");
return;
}
if (OutputPort.SupportsDigitalOutput)
{
Debug.LogMessage(LogEventLevel.Information, this, "Passed the Check");
OutputPort.DigitalOut = state;
}
else
{
Debug.LogMessage(LogEventLevel.Information, this, "Versiport does not support Digital Output Mode");
}
outputPort.DigitalOut = state;
}
#region Bridge Linking
@@ -101,12 +114,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
else
{
this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
try
{
this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state
OutputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OutputState.JoinNumber]);
@@ -114,8 +127,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
catch (Exception e)
{
this.LogError("Unable to link device: {message}", e.Message);
this.LogDebug(e, "Stack Trace: ");
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
}
}
@@ -127,28 +140,41 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary>
public static Versiport GetVersiportDigitalOutput(IOPortConfig dc)
{
if (dc.PortDeviceKey.Equals("processor"))
{
if (!Global.ControlSystem.SupportsVersiport)
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor"))
{
Debug.LogError("GetVersiportDigitalOutput: Processor does not support Versiports");
if (!Global.ControlSystem.SupportsVersiport)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Processor does not support Versiports");
return null;
}
ioPortDevice = Global.ControlSystem;
}
else
{
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
if (ioPortDev == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device '0' is not a valid IOPorts Device", dc.PortDeviceKey);
return null;
}
return Global.ControlSystem.VersiPorts[dc.PortNumber];
}
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
{
Debug.LogError("GetVersiportDigitalOutput: Device {key} is not a valid device", dc.PortDeviceKey);
return null;
}
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
}
var port = ioPortDevice.VersiPorts[dc.PortNumber];
return port;
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOutput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
return null;
}
return ioPortDevice.VersiPorts[dc.PortNumber];
}
}
@@ -158,18 +184,18 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary>
public class GenericVersiportDigitalOutputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
{
/// <summary>
/// Initialize a new instance of the <see cref="GenericVersiportDigitalOutputDeviceFactory"/> class.
/// </summary>
public GenericVersiportDigitalOutputDeviceFactory()
{
TypeNames = new List<string>() { "versiportoutput" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogDebug("Factory Attempting to create new Generic Versiport Device");
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device");
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());

View File

@@ -12,12 +12,6 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary>
public interface IAnalogInput
{
/// <summary>
/// Get the InputValueFeedback.
/// </summary>
/// <remarks>
/// Updates when the analog input value changes
/// </remarks>
IntFeedback InputValueFeedback { get; }
}
}

View File

@@ -14,28 +14,25 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary>
public class IOPortConfig
{
[JsonProperty("portDeviceKey")]
/// <summary>
/// Gets or sets the PortDeviceKey
/// </summary>
[JsonProperty("portDeviceKey")]
public string PortDeviceKey { get; set; }
[JsonProperty("portNumber")]
/// <summary>
/// Gets or sets the PortNumber
/// </summary>
[JsonProperty("portNumber")]
public uint PortNumber { get; set; }
[JsonProperty("disablePullUpResistor")]
/// <summary>
/// Gets or sets the DisablePullUpResistor
/// </summary>
[JsonProperty("disablePullUpResistor")]
public bool DisablePullUpResistor { get; set; }
[JsonProperty("minimumChange")]
/// <summary>
/// Gets or sets the MinimumChange
/// </summary>
[JsonProperty("minimumChange")]
public int MinimumChange { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
using PepperDash.Core;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
/// <summary>
/// Use this interface on a device or room if it uses custom Mobile Control messengers
/// </summary>
public interface ICustomMobileControl : IKeyed
{
}
}

View File

@@ -1,72 +1,155 @@
using System;
using System.Collections.ObjectModel;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
/// <summary>
/// Use this interface on a device or room if it uses custom Mobile Control messengers
/// </summary>
public interface ICustomMobileControl : IKeyed
{
}
/*/// <summary>
/// Describes a MobileControlSystemController
/// </summary>
public interface IMobileControl : IKeyed
{
void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent);
void LinkSystemMonitorToAppServer();
}*/
/// <summary>
/// Defines the contract for IMobileControl
/// </summary>
public interface IMobileControl : IKeyed
{
/// <summary>
/// Gets the Host
/// </summary>
string Host { get; }
/// <summary>
/// Gets the Client App URL
/// </summary>
string ClientAppUrl { get; }
/// <summary>
/// Gets the System UUID
/// </summary>
string SystemUuid { get; }
/// <summary>
/// Gets the ApiOnlineAndAuthorized feedback
/// </summary>
BoolFeedback ApiOnlineAndAuthorized { get; }
/// <summary>
/// Sends the message object to the AppServer
/// </summary>
/// <param name="o">Message to send</param>
void SendMessageObject(IMobileControlMessage o);
/// <summary>
/// Adds an action for a messenger
/// </summary>
/// <typeparam name="T">Messenger type. Must implement IMobileControlMessenger</typeparam>
/// <param name="messenger">messenger to register</param>
/// <param name="action">action to add</param>
void AddAction<T>(T messenger, Action<string, string, JToken> action) where T : IMobileControlMessenger;
/// <summary>
/// Removes an action for a messenger
/// </summary>
/// <param name="key">key for action</param>
void RemoveAction(string key);
/// <summary>
/// Adds a device messenger
/// </summary>
/// <param name="messenger">Messenger to add</param>
void AddDeviceMessenger(IMobileControlMessenger messenger);
/// <summary>
/// Check if a device messenger exists
/// </summary>
/// <param name="key">Messenger key to find</param>
bool CheckForDeviceMessenger(string key);
/// <summary>
/// Get a Room Messenger by key
/// </summary>
/// <param name="key">messenger key to find</param>
/// <returns>Messenger if found, null otherwise</returns>
IMobileControlRoomMessenger GetRoomMessenger(string key);
}
/// <summary>
/// Defines the contract for IMobileControlMessenger
/// </summary>
public interface IMobileControlMessenger : IKeyed
{
IMobileControl AppServerController { get; }
string MessagePath { get; }
string DeviceKey { get; }
void RegisterWithAppServer(IMobileControl appServerController);
}
public interface IMobileControlMessage
{
[JsonProperty("type")]
string Type { get; }
[JsonProperty("clientId", NullValueHandling = NullValueHandling.Ignore)]
string ClientId { get; }
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
JToken Content { get; }
}
/// <summary>
/// Defines the contract for IMobileControlRoomMessenger
/// </summary>
public interface IMobileControlRoomMessenger : IKeyed
{
event EventHandler<EventArgs> UserCodeChanged;
event EventHandler<EventArgs> UserPromptedForCode;
event EventHandler<EventArgs> ClientJoined;
event EventHandler<EventArgs> AppUrlChanged;
string UserCode { get; }
string QrCodeUrl { get; }
string QrCodeChecksum { get; }
string McServerUrl { get; }
string RoomName { get; }
string AppUrl { get; }
void UpdateAppUrl(string url);
}
/// <summary>
/// Defines the contract for IMobileControlAction
/// </summary>
public interface IMobileControlAction
{
IMobileControlMessenger Messenger { get; }
Action<string, string, JToken> Action { get; }
}
/// <summary>
/// Defines the contract for IMobileControlTouchpanelController
/// </summary>
public interface IMobileControlTouchpanelController : IKeyed
{
/// <summary>
/// The default room key for the controller
/// </summary>
string DefaultRoomKey { get; }
/// <summary>
/// Sets the application URL for the controller
/// </summary>
/// <param name="url">The application URL</param>
void SetAppUrl(string url);
/// <summary>
/// Indicates whether the controller uses a direct server connection
/// </summary>
bool UseDirectServer { get; }
/// <summary>
/// Indicates whether the controller is a Zoom Room controller
/// </summary>
bool ZoomRoomController { get; }
}
/// <summary>
/// Describes a MobileControl Crestron Touchpanel Controller
/// This interface extends the IMobileControlTouchpanelController to include connected IP information
/// </summary>
public interface IMobileControlCrestronTouchpanelController : IMobileControlTouchpanelController
{
/// <summary>
/// Gets a collection of connected IP information for the touchpanel controller
/// </summary>
ReadOnlyCollection<ConnectedIpInformation> ConnectedIps { get; }
}
}

View File

@@ -1,15 +0,0 @@
using System;
using Newtonsoft.Json.Linq;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
/// <summary>
/// Defines the contract for IMobileControlAction
/// </summary>
public interface IMobileControlAction
{
IMobileControlMessenger Messenger { get; }
Action<string, string, JToken> Action { get; }
}
}

View File

@@ -1,17 +0,0 @@
using System.Collections.ObjectModel;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
/// <summary>
/// Describes a MobileControl Crestron Touchpanel Controller
/// This interface extends the IMobileControlTouchpanelController to include connected IP information
/// </summary>
public interface IMobileControlCrestronTouchpanelController : IMobileControlTouchpanelController
{
/// <summary>
/// Gets a collection of connected IP information for the touchpanel controller
/// </summary>
ReadOnlyCollection<ConnectedIpInformation> ConnectedIps { get; }
}
}

View File

@@ -1,18 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
public interface IMobileControlMessage
{
[JsonProperty("type")]
string Type { get; }
[JsonProperty("clientId", NullValueHandling = NullValueHandling.Ignore)]
string ClientId { get; }
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
JToken Content { get; }
}
}

View File

@@ -1,31 +0,0 @@
using PepperDash.Core;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
/// <summary>
/// Defines the contract for IMobileControlMessenger
/// </summary>
public interface IMobileControlMessenger : IKeyed
{
/// <summary>
/// Parent controller for this messenger
/// </summary>
IMobileControl AppServerController { get; }
/// <summary>
/// Path to listen for messages
/// </summary>
string MessagePath { get; }
/// <summary>
/// Key of the device this messenger is associated with
/// </summary>
string DeviceKey { get; }
/// <summary>
/// Register this messenger with the AppServerController
/// </summary>
/// <param name="appServerController"></param>
void RegisterWithAppServer(IMobileControl appServerController);
}
}

View File

@@ -1,23 +0,0 @@
using PepperDash.Core;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
/// <summary>
/// Defines the contract for IMobileControlMessenger
/// </summary>
public interface IMobileControlMessengerWithSubscriptions : IMobileControlMessenger
{
/// <summary>
/// Unsubscribe a client from this messenger
/// </summary>
/// <param name="clientId"></param>
void UnsubscribeClient(string clientId);
/// <summary>
/// Register this messenger with the AppServerController
/// </summary>
/// <param name="appServerController">parent for this messenger</param>
/// <param name="enableMessengerSubscriptions">Enable messenger subscriptions</param>
void RegisterWithAppServer(IMobileControl appServerController, bool enableMessengerSubscriptions);
}
}

View File

@@ -1,33 +0,0 @@
using System;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
/// <summary>
/// Defines the contract for IMobileControlRoomMessenger
/// </summary>
public interface IMobileControlRoomMessenger : IKeyed
{
event EventHandler<EventArgs> UserCodeChanged;
event EventHandler<EventArgs> UserPromptedForCode;
event EventHandler<EventArgs> ClientJoined;
event EventHandler<EventArgs> AppUrlChanged;
string UserCode { get; }
string QrCodeUrl { get; }
string QrCodeChecksum { get; }
string McServerUrl { get; }
string RoomName { get; }
string AppUrl { get; }
void UpdateAppUrl(string url);
}
}

View File

@@ -1,31 +0,0 @@
using PepperDash.Core;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
/// <summary>
/// Defines the contract for IMobileControlTouchpanelController
/// </summary>
public interface IMobileControlTouchpanelController : IKeyed
{
/// <summary>
/// The default room key for the controller
/// </summary>
string DefaultRoomKey { get; }
/// <summary>
/// Sets the application URL for the controller
/// </summary>
/// <param name="url">The application URL</param>
void SetAppUrl(string url);
/// <summary>
/// Indicates whether the controller uses a direct server connection
/// </summary>
bool UseDirectServer { get; }
/// <summary>
/// Indicates whether the controller is a Zoom Room controller
/// </summary>
bool ZoomRoomController { get; }
}
}

View File

@@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Core
public List<string> TypeNames { get; protected set; }
/// <summary>
/// Build the device using the configuration
/// The method that will build the device
/// </summary>
/// <param name="dc">The device config</param>
/// <returns>An instance of the device</returns>

View File

@@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Core
public interface IHasFeedback : IKeyed
{
/// <summary>
/// This method returns a list of all Output objects on a device,
/// This method shall return a list of all Output objects on a device,
/// including all "aggregate" devices.
/// </summary>
FeedbackCollection<Feedback> Feedbacks { get; }

View File

@@ -0,0 +1,326 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Enum for camera control modes
/// </summary>
public enum eCameraControlMode
{
/// <summary>
/// Manual control mode, where the camera is controlled directly by the user or system
/// </summary>
Manual = 0,
/// <summary>
/// Off control mode, where the camera is turned off or disabled
/// </summary>
Off,
/// <summary>
/// Auto control mode, where the camera automatically adjusts settings based on the environment or conditions
/// </summary>
Auto
}
/// <summary>
/// Interface for devices that have cameras
/// </summary>
public interface IHasCameras : IKeyName
{
/// <summary>
/// Event that is raised when a camera is selected
/// </summary>
event EventHandler<CameraSelectedEventArgs> CameraSelected;
/// <summary>
/// List of cameras on the device. This should be a list of CameraBase objects
/// </summary>
List<CameraBase> Cameras { get; }
/// <summary>
/// The currently selected camera. This should be a CameraBase object
/// </summary>
CameraBase SelectedCamera { get; }
/// <summary>
/// Feedback that indicates the currently selected camera
/// </summary>
StringFeedback SelectedCameraFeedback { get; }
/// <summary>
/// Selects a camera from the list of available cameras based on the provided key.
/// </summary>
/// <param name="key">The unique identifier or name of the camera to select.</param>
void SelectCamera(string key);
}
/// <summary>
/// Defines the contract for IHasCodecCameras
/// </summary>
public interface IHasCodecCameras : IHasCameras, IHasFarEndCameraControl
{
}
/// <summary>
/// To be implmented on codecs that can disable their camera(s) to blank the near end video
/// </summary>
public interface IHasCameraOff
{
/// <summary>
/// Feedback that indicates whether the camera is off
/// </summary>
BoolFeedback CameraIsOffFeedback { get; }
/// <summary>
/// Turns the camera off, blanking the near end video
/// </summary>
void CameraOff();
}
/// <summary>
/// Describes the ability to mute and unmute camera video
/// </summary>
public interface IHasCameraMute
{
/// <summary>
/// Feedback that indicates whether the camera is muted
/// </summary>
BoolFeedback CameraIsMutedFeedback { get; }
/// <summary>
/// Mutes the camera video, preventing it from being sent to the far end
/// </summary>
void CameraMuteOn();
/// <summary>
/// Unmutes the camera video, allowing it to be sent to the far end
/// </summary>
void CameraMuteOff();
/// <summary>
/// Toggles the camera mute state. If the camera is muted, it will be unmuted, and vice versa.
/// </summary>
void CameraMuteToggle();
}
/// <summary>
/// Interface for devices that can mute and unmute their camera video, with an event for unmute requests
/// </summary>
public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute
{
/// <summary>
/// Event that is raised when a video unmute is requested, typically by the far end
/// </summary>
event EventHandler VideoUnmuteRequested;
}
/// <summary>
/// Event arguments for the CameraSelected event
/// </summary>
public class CameraSelectedEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the SelectedCamera
/// </summary>
public CameraBase SelectedCamera { get; private set; }
/// <summary>
/// Constructor for CameraSelectedEventArgs
/// </summary>
/// <param name="camera"></param>
public CameraSelectedEventArgs(CameraBase camera)
{
SelectedCamera = camera;
}
}
/// <summary>
/// Interface for devices that have a far end camera control
/// </summary>
public interface IHasFarEndCameraControl
{
/// <summary>
/// Gets the far end camera, which is typically a CameraBase object that represents the camera at the far end of a call
/// </summary>
CameraBase FarEndCamera { get; }
/// <summary>
/// Feedback that indicates whether the far end camera is being controlled
/// </summary>
BoolFeedback ControllingFarEndCameraFeedback { get; }
}
/// <summary>
/// Defines the contract for IAmFarEndCamera
/// </summary>
public interface IAmFarEndCamera
{
}
/// <summary>
/// Interface for devices that have camera controls
/// </summary>
public interface IHasCameraControls
{
}
/// <summary>
/// Defines the contract for IHasCameraPtzControl
/// </summary>
public interface IHasCameraPtzControl : IHasCameraPanControl, IHasCameraTiltControl, IHasCameraZoomControl
{
/// <summary>
/// Resets the camera position
/// </summary>
void PositionHome();
}
/// <summary>
/// Interface for camera pan control
/// </summary>
public interface IHasCameraPanControl : IHasCameraControls
{
/// <summary>
/// Pans the camera left
/// </summary>
void PanLeft();
/// <summary>
/// Pans the camera right
/// </summary>
void PanRight();
/// <summary>
/// Stops the camera pan movement
/// </summary>
void PanStop();
}
/// <summary>
/// Defines the contract for IHasCameraTiltControl
/// </summary>
public interface IHasCameraTiltControl : IHasCameraControls
{
/// <summary>
/// Tilts the camera down
/// </summary>
void TiltDown();
/// <summary>
/// Tilts the camera up
/// </summary>
void TiltUp();
/// <summary>
/// Stops the camera tilt movement
/// </summary>
void TiltStop();
}
/// <summary>
/// Defines the contract for IHasCameraZoomControl
/// </summary>
public interface IHasCameraZoomControl : IHasCameraControls
{
/// <summary>
/// Zooms the camera in
/// </summary>
void ZoomIn();
/// <summary>
/// Zooms the camera out
/// </summary>
void ZoomOut();
/// <summary>
/// Stops the camera zoom movement
/// </summary>
void ZoomStop();
}
/// <summary>
/// Defines the contract for IHasCameraFocusControl
/// </summary>
public interface IHasCameraFocusControl : IHasCameraControls
{
/// <summary>
/// Focuses the camera near
/// </summary>
void FocusNear();
/// <summary>
/// Focuses the camera far
/// </summary>
void FocusFar();
/// <summary>
/// Stops the camera focus movement
/// </summary>
void FocusStop();
/// <summary>
/// Triggers the camera's auto focus functionality, if available.
/// </summary>
void TriggerAutoFocus();
}
/// <summary>
/// Interface for devices that have auto focus mode control
/// </summary>
public interface IHasAutoFocusMode
{
/// <summary>
/// Sets the focus mode to auto or manual, or toggles between them.
/// </summary>
void SetFocusModeAuto();
/// <summary>
/// Sets the focus mode to manual, allowing for manual focus adjustments.
/// </summary>
void SetFocusModeManual();
/// <summary>
/// Toggles the focus mode between auto and manual.
/// </summary>
void ToggleFocusMode();
}
/// <summary>
/// Interface for devices that have camera auto mode control
/// </summary>
public interface IHasCameraAutoMode : IHasCameraControls
{
/// <summary>
/// Enables or disables the camera's auto mode, which may include automatic adjustments for focus, exposure, and other settings.
/// </summary>
void CameraAutoModeOn();
/// <summary>
/// Disables the camera's auto mode, allowing for manual control of camera settings.
/// </summary>
void CameraAutoModeOff();
/// <summary>
/// Toggles the camera's auto mode state. If the camera is in auto mode, it will switch to manual mode, and vice versa.
/// </summary>
void CameraAutoModeToggle();
/// <summary>
/// Feedback that indicates whether the camera's auto mode is currently enabled.
/// </summary>
BoolFeedback CameraAutoModeIsOnFeedback { get; }
}
}

View File

@@ -1,49 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Event arguments for the CameraSelected event
/// </summary>
[Obsolete("Use CameraSelectedEventArgs<T> instead. This class will be removed in a future version")]
public class CameraSelectedEventArgs : EventArgs
{
/// Gets or sets the SelectedCamera
/// </summary>
public CameraBase SelectedCamera { get; private set; }
/// <summary>
/// Constructor for CameraSelectedEventArgs
/// </summary>
/// <param name="camera"></param>
public CameraSelectedEventArgs(CameraBase camera)
{
SelectedCamera = camera;
}
}
/// <summary>
/// Event arguments for the CameraSelected event
/// </summary>
/// <typeparam name="T"></typeparam>
public class CameraSelectedEventArgs<T> : EventArgs
{
/// <summary>
/// Gets or sets the SelectedCamera
/// </summary>
public T SelectedCamera { get; private set; }
/// <summary>
/// Constructor for CameraSelectedEventArgs
/// </summary>
/// <param name="camera"></param>
public CameraSelectedEventArgs(T camera)
{
SelectedCamera = camera;
}
}
}

View File

@@ -1,12 +0,0 @@
using PepperDash.Core;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Defines the contract for IAmFarEndCamera
/// </summary>
public interface IAmFarEndCamera : IKeyName
{
}
}

View File

@@ -1,86 +0,0 @@
using Newtonsoft.Json;
using PepperDash.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Interface for camera capabilities
/// </summary>
public interface ICameraCapabilities: IKeyName
{
/// <summary>
/// Indicates whether the camera can pan
/// </summary>
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
bool CanPan { get; }
/// <summary>
/// Indicates whether the camera can tilt
/// </summary>
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
bool CanTilt { get; }
/// <summary>
/// Indicates whether the camera can zoom
/// </summary>
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
bool CanZoom { get; }
/// <summary>
/// Indicates whether the camera can focus
/// </summary>
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
bool CanFocus { get; }
}
/// <summary>
/// Indicates the capabilities of a camera
/// </summary>
public class CameraCapabilities : ICameraCapabilities
{
/// <summary>
/// Unique Key
/// </summary>
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
public string Key { get; set; }
/// <summary>
/// Isn't it obvious :)
/// </summary>
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }
/// <summary>
/// Indicates whether the camera can pan
/// </summary>
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
public bool CanPan { get; set; }
/// <summary>
/// Indicates whether the camera can tilt
/// </summary>
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
public bool CanTilt { get; set; }
/// <summary>
/// Indicates whether the camera can zoom
/// </summary>
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
public bool CanZoom { get; set; }
/// <summary>
/// Indicates whether the camera can focus
/// </summary>
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
public bool CanFocus { get; set; }
}
}

View File

@@ -1,24 +0,0 @@
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Interface for devices that have auto focus mode control
/// </summary>
public interface IHasAutoFocusMode : IHasCameraControls
{
/// <summary>
/// Sets the focus mode to auto or manual, or toggles between them.
/// </summary>
void SetFocusModeAuto();
/// <summary>
/// Sets the focus mode to manual, allowing for manual focus adjustments.
/// </summary>
void SetFocusModeManual();
/// <summary>
/// Toggles the focus mode between auto and manual.
/// </summary>
void ToggleFocusMode();
}
}

View File

@@ -1,31 +0,0 @@
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Interface for devices that have camera auto mode control
/// </summary>
public interface IHasCameraAutoMode : IHasCameraControls
{
/// <summary>
/// Enables or disables the camera's auto mode, which may include automatic adjustments for focus, exposure, and other settings.
/// </summary>
void CameraAutoModeOn();
/// <summary>
/// Disables the camera's auto mode, allowing for manual control of camera settings.
/// </summary>
void CameraAutoModeOff();
/// <summary>
/// Toggles the camera's auto mode state. If the camera is in auto mode, it will switch to manual mode, and vice versa.
/// </summary>
void CameraAutoModeToggle();
/// <summary>
/// Feedback that indicates whether the camera's auto mode is currently enabled.
/// </summary>
BoolFeedback CameraAutoModeIsOnFeedback { get; }
}
}

View File

@@ -1,13 +0,0 @@
using PepperDash.Core;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Interface for devices that have camera controls
/// </summary>
public interface IHasCameraControls : IKeyName
{
}
}

View File

@@ -1,29 +0,0 @@
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Defines the contract for IHasCameraFocusControl
/// </summary>
public interface IHasCameraFocusControl : IHasCameraControls
{
/// <summary>
/// Focuses the camera near
/// </summary>
void FocusNear();
/// <summary>
/// Focuses the camera far
/// </summary>
void FocusFar();
/// <summary>
/// Stops the camera focus movement
/// </summary>
void FocusStop();
/// <summary>
/// Triggers the camera's auto focus functionality, if available.
/// </summary>
void TriggerAutoFocus();
}
}

View File

@@ -1,31 +0,0 @@
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Describes the ability to mute and unmute camera video
/// </summary>
public interface IHasCameraMute : IKeyName
{
/// <summary>
/// Feedback that indicates whether the camera is muted
/// </summary>
BoolFeedback CameraIsMutedFeedback { get; }
/// <summary>
/// Mutes the camera video, preventing it from being sent to the far end
/// </summary>
void CameraMuteOn();
/// <summary>
/// Unmutes the camera video, allowing it to be sent to the far end
/// </summary>
void CameraMuteOff();
/// <summary>
/// Toggles the camera mute state. If the camera is muted, it will be unmuted, and vice versa.
/// </summary>
void CameraMuteToggle();
}
}

View File

@@ -1,16 +0,0 @@
using System;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Interface for devices that can mute and unmute their camera video, with an event for unmute requests
/// </summary>
public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute
{
/// <summary>
/// Event that is raised when a video unmute is requested, typically by the far end
/// </summary>
event EventHandler VideoUnmuteRequested;
}
}

View File

@@ -1,27 +0,0 @@
using PepperDash.Essentials.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// To be implmented on codecs that can disable their camera(s) to blank the near end video
/// </summary>
public interface IHasCameraOff : IHasCameraControls
{
/// <summary>
/// Feedback that indicates whether the camera is off
/// </summary>
BoolFeedback CameraIsOffFeedback { get; }
/// <summary>
/// Turns the camera off, blanking the near end video
/// </summary>
void CameraOff();
}
}

View File

@@ -1,24 +0,0 @@
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Interface for camera pan control
/// </summary>
public interface IHasCameraPanControl : IHasCameraControls
{
/// <summary>
/// Pans the camera left
/// </summary>
void PanLeft();
/// <summary>
/// Pans the camera right
/// </summary>
void PanRight();
/// <summary>
/// Stops the camera pan movement
/// </summary>
void PanStop();
}
}

View File

@@ -1,14 +0,0 @@
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Defines the contract for IHasCameraPtzControl
/// </summary>
public interface IHasCameraPtzControl : IHasCameraPanControl, IHasCameraTiltControl, IHasCameraZoomControl
{
/// <summary>
/// Resets the camera position
/// </summary>
void PositionHome();
}
}

View File

@@ -1,24 +0,0 @@
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Defines the contract for IHasCameraTiltControl
/// </summary>
public interface IHasCameraTiltControl : IHasCameraControls
{
/// <summary>
/// Tilts the camera down
/// </summary>
void TiltDown();
/// <summary>
/// Tilts the camera up
/// </summary>
void TiltUp();
/// <summary>
/// Stops the camera tilt movement
/// </summary>
void TiltStop();
}
}

View File

@@ -1,24 +0,0 @@
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Defines the contract for IHasCameraZoomControl
/// </summary>
public interface IHasCameraZoomControl : IHasCameraControls
{
/// <summary>
/// Zooms the camera in
/// </summary>
void ZoomIn();
/// <summary>
/// Zooms the camera out
/// </summary>
void ZoomOut();
/// <summary>
/// Stops the camera zoom movement
/// </summary>
void ZoomStop();
}
}

View File

@@ -1,41 +0,0 @@
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Interface for devices that have cameras
/// </summary>
[Obsolete("Use IHasCamerasWithControls instead. This interface will be removed in a future version")]
public interface IHasCameras : IKeyName
{
/// <summary>
/// Event that is raised when a camera is selected
/// </summary>
event EventHandler<CameraSelectedEventArgs> CameraSelected;
/// <summary>
/// List of cameras on the device. This should be a list of CameraBase objects
/// </summary>
List<CameraBase> Cameras { get; }
/// <summary>
/// The currently selected camera. This should be a CameraBase object
/// </summary>
CameraBase SelectedCamera { get; }
/// <summary>
/// Feedback that indicates the currently selected camera
/// </summary>
StringFeedback SelectedCameraFeedback { get; }
/// <summary>
/// Selects a camera from the list of available cameras based on the provided key.
/// </summary>
/// <param name="key">The unique identifier or name of the camera to select.</param>
void SelectCamera(string key);
}
}

View File

@@ -1,40 +0,0 @@
using PepperDash.Core;
using PepperDash.Essentials.Core;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Interface for devices that have cameras with controls
/// </summary>
public interface IHasCamerasWithControls : IKeyName, IKeyed
{
/// <summary>
/// List of cameras on the device. This should be a list of IHasCameraControls objects
/// </summary>
List<IHasCameraControls> Cameras { get; }
/// <summary>
/// The currently selected camera. This should be an IHasCameraControls object
/// </summary>
IHasCameraControls SelectedCamera { get; }
/// <summary>
/// Feedback that indicates the currently selected camera
/// </summary>
StringFeedback SelectedCameraFeedback { get; }
/// <summary>
/// Event that is raised when a camera is selected
/// </summary>
event EventHandler<CameraSelectedEventArgs<IHasCameraControls>> CameraSelected;
/// <summary>
/// Selects a camera from the list of available cameras based on the provided key.
/// </summary>
/// <param name="key"></param>
void SelectCamera(string key);
}
}

View File

@@ -1,13 +0,0 @@
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Defines the contract for IHasCodecCameras
/// </summary>
public interface IHasCodecCameras : IHasCameras, IHasFarEndCameraControl
{
}
}

View File

@@ -1,23 +0,0 @@
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Interface for devices that have a far end camera control
/// </summary>
public interface IHasFarEndCameraControl : IKeyName
{
/// <summary>
/// Gets the far end camera, which is typically a CameraBase object that represents the camera at the far end of a call
/// </summary>
CameraBase FarEndCamera { get; }
/// <summary>
/// Feedback that indicates whether the far end camera is being controlled
/// </summary>
BoolFeedback ControllingFarEndCameraFeedback { get; }
}
}

View File

@@ -1,24 +0,0 @@
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Enum for camera control modes
/// </summary>
public enum eCameraControlMode
{
/// <summary>
/// Manual control mode, where the camera is controlled directly by the user or system
/// </summary>
Manual = 0,
/// <summary>
/// Off control mode, where the camera is turned off or disabled
/// </summary>
Off,
/// <summary>
/// Auto control mode, where the camera automatically adjusts settings based on the environment or conditions
/// </summary>
Auto
}
}

View File

@@ -1,8 +1,8 @@
using System;
using System.Linq;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Devices.Common.AudioCodec;
using PepperDash.Essentials.Devices.Common.Codec;
using System;
using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -29,16 +29,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
codec.CallStatusChange += Codec_CallStatusChange;
}
/// <inheritdoc />
protected override void RegisterActions()
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendAtcFullMessageObject(id));
AddAction("/audioDialerStatus", (id, content) => SendAtcFullMessageObject(id));
AddAction("/fullStatus", (id, content) => SendAtcFullMessageObject());
AddAction("/dial", (id, content) =>
{
var msg = content.ToObject<MobileControlSimpleContent<string>>();
@@ -101,7 +97,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// Helper method to build call status for vtc
/// </summary>
/// <returns></returns>
private void SendAtcFullMessageObject(string id = null)
private void SendAtcFullMessageObject()
{
var info = Codec.CodecInfo;
@@ -113,7 +109,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
phoneNumber = info.PhoneNumber
}
}), id
})
);
}
}

View File

@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Cameras;
@@ -11,12 +9,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary>
/// Messenger for a CameraBase device
/// </summary>
public class CameraBaseMessenger<T> : MessengerBase where T : IKeyed
public class CameraBaseMessenger : MessengerBase
{
/// <summary>
/// Gets or sets the Camera
/// </summary>
public T Camera { get; set; }
public CameraBase Camera { get; set; }
/// <summary>
/// Constructor
@@ -24,13 +22,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <param name="key"></param>
/// <param name="camera"></param>
/// <param name="messagePath"></param>
public CameraBaseMessenger(string key, T camera, string messagePath)
: base(key, messagePath, camera as IKeyName)
public CameraBaseMessenger(string key, CameraBase camera, string messagePath)
: base(key, messagePath, camera)
{
if (camera == null)
throw new ArgumentNullException(nameof(camera));
Camera = camera;
Camera = camera ?? throw new ArgumentNullException("camera");
if (Camera is IHasCameraPresets presetsCamera)
@@ -60,9 +55,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject(id));
AddAction("/cameraStatus", (id, content) => SendCameraFullMessageObject(id));
AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject());
if (Camera is IHasCameraPtzControl ptzCamera)
@@ -180,47 +173,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary>
/// Helper method to update the full status of the camera
/// </summary>
private void SendCameraFullMessageObject(string id = null)
private void SendCameraFullMessageObject()
{
var presetList = new List<CameraPreset>();
CameraCapabilities capabilities = null;
if (Camera is IHasCameraPresets presetsCamera)
presetList = presetsCamera.Presets;
if (Camera is ICameraCapabilities cameraCapabilities)
capabilities = new CameraCapabilities
{
CanPan = cameraCapabilities.CanPan,
CanTilt = cameraCapabilities.CanTilt,
CanZoom = cameraCapabilities.CanZoom,
CanFocus = cameraCapabilities.CanFocus
};
if (Camera is CameraBase cameraBase)
capabilities = new CameraCapabilities
{
CanPan = cameraBase.CanPan,
CanTilt = cameraBase.CanTilt,
CanZoom = cameraBase.CanZoom,
CanFocus = cameraBase.CanFocus
};
var message = new CameraStateMessage
PostStatusMessage(JToken.FromObject(new
{
CameraManualSupported = Camera is IHasCameraControls,
CameraAutoSupported = Camera is IHasCameraAutoMode,
CameraOffSupported = Camera is IHasCameraOff,
CameraMode = (eCameraControlMode)Enum.Parse(typeof(eCameraControlMode), GetCameraMode(), true),
HasPresets = Camera is IHasCameraPresets,
Presets = presetList,
Capabilities = capabilities,
IsFarEnd = Camera is IAmFarEndCamera
};
PostStatusMessage(message, id
cameraManualSupported = Camera is IHasCameraControls,
cameraAutoSupported = Camera is IHasCameraAutoMode,
cameraOffSupported = Camera is IHasCameraOff,
cameraMode = GetCameraMode(),
hasPresets = Camera is IHasCameraPresets,
presets = presetList
})
);
}
@@ -240,59 +208,4 @@ namespace PepperDash.Essentials.AppServer.Messengers
return m;
}
}
/// <summary>
/// State message for a camera device
/// </summary>
public class CameraStateMessage : DeviceStateMessageBase
{
/// <summary>
/// Indicates whether the camera supports manual control
/// </summary>
[JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)]
public bool CameraManualSupported { get; set; }
/// <summary>
/// Indicates whether the camera supports auto control
/// </summary>
[JsonProperty("cameraAutoSupported", NullValueHandling = NullValueHandling.Ignore)]
public bool CameraAutoSupported { get; set; }
/// <summary>
/// Indicates whether the camera supports off control
/// </summary>
[JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)]
public bool CameraOffSupported { get; set; }
/// <summary>
/// Indicates the current camera control mode
/// </summary>
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public eCameraControlMode CameraMode { get; set; }
/// <summary>
/// Indicates whether the camera has presets
/// </summary>
[JsonProperty("hasPresets", NullValueHandling = NullValueHandling.Ignore)]
public bool HasPresets { get; set; }
/// <summary>
/// List of presets if the camera supports them
/// </summary>
[JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)]
public List<CameraPreset> Presets { get; set; }
/// <summary>
/// Indicates the capabilities of the camera
/// </summary>
[JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)]
public CameraCapabilities Capabilities { get; set; }
/// <summary>
/// Indicates whether the camera is a far end camera
/// </summary>
[JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)]
public bool IsFarEnd { get; set; }
}
}

View File

@@ -33,9 +33,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendCurrentSourceStatus(id));
AddAction("/fullStatus", (id, content) =>
{
var message = new CurrentSourcesStateMessage
{
CurrentSourceKeys = sourceDevice.CurrentSourceKeys,
CurrentSources = sourceDevice.CurrentSources
};
AddAction("/currentSourceStatus", (id, content) => SendCurrentSourceStatus(id));
PostStatusMessage(message);
});
sourceDevice.CurrentSourcesChanged += (sender, e) =>
{
@@ -46,17 +53,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
}));
};
}
private void SendCurrentSourceStatus(string id = null)
{
var message = new CurrentSourcesStateMessage
{
CurrentSourceKeys = sourceDevice.CurrentSourceKeys,
CurrentSources = sourceDevice.CurrentSources
};
PostStatusMessage(message, id);
}
}
/// <summary>

View File

@@ -1,17 +0,0 @@
using Newtonsoft.Json;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Base class for event messages that include the type of message and an event type
/// </summary>
public abstract class DeviceEventMessageBase : DeviceMessageBase
{
/// <summary>
/// The event type
/// </summary>
[JsonProperty("eventType")]
public string EventType { get; set; }
}
}

View File

@@ -1,8 +1,8 @@
using System.Timers;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceInfo;
using System.Timers;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -67,19 +67,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
debounceTimer.Start();
};
AddAction("/fullStatus", (id, context) => SendFullStatus(id));
AddAction("/deviceInfo", (id, content) => SendFullStatus(id));
AddAction("/update", (id, context) => _deviceInfoProvider.UpdateDeviceInfo());
}
private void SendFullStatus(string id = null)
{
PostStatusMessage(new DeviceInfoStateMessage
AddAction("/fullStatus", (id, context) => PostStatusMessage(new DeviceInfoStateMessage
{
DeviceInfo = _deviceInfoProvider.DeviceInfo
}, id);
}));
AddAction("/update", (id, context) => _deviceInfoProvider.UpdateDeviceInfo());
}
}

View File

@@ -1,39 +0,0 @@
using Newtonsoft.Json;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Base class for device messages that include the type of message
/// </summary>
public abstract class DeviceMessageBase
{
/// <summary>
/// The device key
/// </summary>
[JsonProperty("key")]
/// <summary>
/// Gets or sets the Key
/// </summary>
public string Key { get; set; }
/// <summary>
/// The device name
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// The type of the message class
/// </summary>
[JsonProperty("messageType")]
public string MessageType => GetType().Name;
/// <summary>
/// Gets or sets the MessageBasePath
/// </summary>
[JsonProperty("messageBasePath")]
public string MessageBasePath { get; set; }
}
}

View File

@@ -1,11 +1,11 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Core.Presets;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -16,24 +16,18 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
private readonly ITvPresetsProvider _presetsDevice;
/// <summary>
/// Constructor for DevicePresetsModelMessenger
/// </summary>
/// <param name="key">The key.</param>
/// <param name="messagePath">The message path.</param>
/// <param name="presetsDevice">The presets device.</param>
public DevicePresetsModelMessenger(string key, string messagePath, ITvPresetsProvider presetsDevice)
: base(key, messagePath, presetsDevice as Device)
{
_presetsDevice = presetsDevice;
}
private void SendPresets(string id = null)
private void SendPresets()
{
PostStatusMessage(new PresetStateMessage
{
Favorites = _presetsDevice.TvPresets.PresetsList
}, id);
});
}
private void RecallPreset(ISetTopBoxNumericKeypad device, string channel)
@@ -49,7 +43,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
#region Overrides of MessengerBase
/// <inheritdoc />
protected override void RegisterActions()
{
@@ -58,7 +51,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
this.LogInformation("getting full status for client {id}", id);
try
{
SendPresets(id);
SendPresets();
}
catch (Exception ex)
{
@@ -66,8 +59,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
});
AddAction("/presetsStatus", (id, content) => SendPresets(id));
AddAction("/recall", (id, content) =>
{
var p = content.ToObject<PresetChannelMessage>();
@@ -100,16 +91,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class PresetChannelMessage
{
[JsonProperty("preset")]
/// <summary>
/// Gets or sets the Preset
/// </summary>
[JsonProperty("preset")]
public PresetChannel Preset;
[JsonProperty("deviceKey")]
/// <summary>
/// Gets or sets the DeviceKey
/// </summary>
[JsonProperty("deviceKey")]
public string DeviceKey;
}
@@ -118,11 +109,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class PresetStateMessage : DeviceStateMessageBase
{
[JsonProperty("favorites", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Favorites
/// </summary>
[JsonProperty("favorites", NullValueHandling = NullValueHandling.Ignore)]
public List<PresetChannel> Favorites { get; set; } = new List<PresetChannel>();
}
}

View File

@@ -1,27 +0,0 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Represents a DeviceStateMessageBase
/// </summary>
public class DeviceStateMessageBase : DeviceMessageBase
{
/// <summary>
/// The interfaces implmented by the device sending the messsage
/// </summary>
[JsonProperty("interfaces")]
public List<string> Interfaces { get; private set; }
/// <summary>
/// Sets the interfaces implemented by the device sending the message
/// </summary>
/// <param name="interfaces"></param>
public void SetInterfaces(List<string> interfaces)
{
Interfaces = interfaces;
}
}
}

View File

@@ -1,10 +1,9 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core;
using System;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -13,46 +12,35 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class DeviceVolumeMessenger : MessengerBase
{
private readonly IBasicVolumeControls device;
private readonly IBasicVolumeWithFeedback _localDevice;
/// <summary>
/// Initializes a new instance of the <see cref="DeviceVolumeMessenger"/> class.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="messagePath">The message path.</param>
/// <param name="device">The device.</param>
public DeviceVolumeMessenger(string key, string messagePath, IBasicVolumeControls device)
public DeviceVolumeMessenger(string key, string messagePath, IBasicVolumeWithFeedback device)
: base(key, messagePath, device as IKeyName)
{
this.device = device;
_localDevice = device;
}
private void SendStatus(string id = null)
private void SendStatus()
{
try
{
if (!(device is IBasicVolumeWithFeedback feedbackDevice))
{
return;
}
var messageObj = new VolumeStateMessage
{
Volume = new Volume
{
Level = feedbackDevice?.VolumeLevelFeedback.IntValue ?? -1,
Muted = feedbackDevice?.MuteFeedback.BoolValue ?? false,
Level = _localDevice?.VolumeLevelFeedback.IntValue ?? -1,
Muted = _localDevice?.MuteFeedback.BoolValue ?? false,
HasMute = true, // assume all devices have mute for now
}
};
if (device is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
if (_localDevice is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
{
messageObj.Volume.RawValue = volumeAdvanced.RawVolumeLevel.ToString();
messageObj.Volume.Units = volumeAdvanced.Units;
}
PostStatusMessage(messageObj, id);
PostStatusMessage(messageObj);
}
catch (Exception ex)
{
@@ -62,26 +50,47 @@ namespace PepperDash.Essentials.AppServer.Messengers
#region Overrides of MessengerBase
/// <inheritdoc />
protected override void RegisterActions()
{
AddAction("/volumeUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) =>
{
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Calling {localDevice} volume up with {value}", DeviceKey, b);
try
{
device.VolumeUp(b);
}
catch (Exception ex)
{
Debug.LogMessage(ex, "Got exception during volume up: {Exception}", null, ex);
}
}));
AddAction("/fullStatus", (id, content) => SendStatus());
AddAction("/level", (id, content) =>
{
var volume = content.ToObject<MobileControlSimpleContent<ushort>>();
_localDevice.SetVolume(volume.Value);
});
AddAction("/muteToggle", (id, content) =>
{
device.MuteToggle();
});
{
_localDevice.MuteToggle();
});
AddAction("/muteOn", (id, content) =>
{
_localDevice.MuteOn();
});
AddAction("/muteOff", (id, content) =>
{
_localDevice.MuteOff();
});
AddAction("/volumeUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) =>
{
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Calling {localDevice} volume up with {value}", DeviceKey, b);
try
{
_localDevice.VolumeUp(b);
}
catch (Exception ex)
{
Debug.LogMessage(ex, "Got exception during volume up: {Exception}", null, ex);
}
}));
AddAction("/volumeDown", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) =>
{
@@ -89,7 +98,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
try
{
device.VolumeDown(b);
_localDevice.VolumeDown(b);
}
catch (Exception ex)
{
@@ -97,38 +106,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
}));
if (!(device is IBasicVolumeWithFeedback feedback))
{
this.LogDebug("Skipping feedback methods for {deviceKey}", (device as IKeyName)?.Key);
return;
}
AddAction("/fullStatus", (id, content) => SendStatus(id));
AddAction("/volumeStatus", (id, content) => SendStatus(id));
AddAction("/level", (id, content) =>
{
var volume = content.ToObject<MobileControlSimpleContent<ushort>>();
feedback.SetVolume(volume.Value);
});
AddAction("/muteOn", (id, content) =>
{
feedback.MuteOn();
});
AddAction("/muteOff", (id, content) =>
{
feedback.MuteOff();
});
feedback.MuteFeedback.OutputChange += (sender, args) =>
_localDevice.MuteFeedback.OutputChange += (sender, args) =>
{
PostStatusMessage(JToken.FromObject(
new
@@ -141,10 +119,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
);
};
feedback.VolumeLevelFeedback.OutputChange += (sender, args) =>
_localDevice.VolumeLevelFeedback.OutputChange += (sender, args) =>
{
var rawValue = "";
if (feedback is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
if (_localDevice is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
{
rawValue = volumeAdvanced.RawVolumeLevel.ToString();
}
@@ -160,6 +138,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostStatusMessage(JToken.FromObject(message));
};
}
#endregion

View File

@@ -7,29 +7,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class GenericMessenger : MessengerBase
{
/// <summary>
/// Initializes a new instance of the <see cref="GenericMessenger"/> class.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="device">The device.</param>
/// <param name="messagePath">The message path.</param>
public GenericMessenger(string key, EssentialsDevice device, string messagePath) : base(key, messagePath, device)
{
}
/// <inheritdoc />
protected override void RegisterActions()
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
var state = new DeviceStateMessageBase();
PostStatusMessage(state, id);
PostStatusMessage(state);
}
}
}

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -13,12 +13,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
private readonly IBasicVideoMuteWithFeedback device;
/// <summary>
/// Initializes a new instance of the <see cref="IBasicVideoMuteWithFeedbackMessenger"/> class.
/// </summary>
/// <param name="key"></param>
/// <param name="messagePath"></param>
/// <param name="device"></param>
public IBasicVideoMuteWithFeedbackMessenger(string key, string messagePath, IBasicVideoMuteWithFeedback device)
: base(key, messagePath, device as IKeyName)
{
@@ -28,24 +22,21 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary>
/// SendFullStatus method
/// </summary>
public void SendFullStatus(string id = null)
public void SendFullStatus()
{
var messageObj = new IBasicVideoMuteWithFeedbackMessage
{
VideoMuteState = device.VideoMuteIsOn.BoolValue
};
PostStatusMessage(messageObj, id);
PostStatusMessage(messageObj);
}
/// <inheritdoc />
protected override void RegisterActions()
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/videoMuteStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/videoMuteToggle", (id, content) =>
{

View File

@@ -24,12 +24,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
AddAction("/fullStatus", (id, content) =>
{
SendFullStatus(id);
});
AddAction("/commStatus", (id, content) =>
{
SendFullStatus(id);
PostStatusMessage(new CommunicationMonitorState
{
CommunicationMonitor = new CommunicationMonitorProps
{
IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline,
Status = _communicationMonitor.CommunicationMonitor.Status
}
});
});
_communicationMonitor.CommunicationMonitor.StatusChange += (sender, args) =>
@@ -44,18 +46,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
}));
};
}
private void SendFullStatus(string id = null)
{
PostStatusMessage(new CommunicationMonitorState
{
CommunicationMonitor = new CommunicationMonitorProps
{
IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline,
Status = _communicationMonitor.CommunicationMonitor.Status
},
}, id);
}
}
/// <summary>

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -22,9 +22,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) =>
{
var message = new IHasDspPresetsStateMessage
{
Presets = device.Presets
};
AddAction("/dspPresetStatus", (id, content) => SendFullStatus(id));
PostStatusMessage(message);
});
AddAction("/recallPreset", (id, content) =>
{
@@ -37,16 +43,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
});
}
private void SendFullStatus(string id = null)
{
var message = new IHasDspPresetsStateMessage
{
Presets = device.Presets
};
PostStatusMessage(message, id);
}
}
/// <summary>

View File

@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -46,9 +46,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// partition states.</remarks>
protected override void RegisterActions()
{
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/combinerStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/setAutoMode", (id, content) =>
{
@@ -122,7 +120,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
try
{
@@ -143,7 +141,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
Partitions = _roomCombiner.Partitions
};
PostStatusMessage(message, id);
PostStatusMessage(message);
}
catch (Exception e)
{

View File

@@ -1,14 +1,17 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Devices.Common.Cameras;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Messenger for devices that implement the IHasCameras interface.
/// </summary>
[Obsolete("Use IHasCamerasWithControlsMessenger instead. This class will be removed in a future version")]
public class IHasCamerasMessenger : MessengerBase
{
/// <summary>
@@ -23,7 +26,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <param name="cameraController"></param>
/// <param name="messagePath"></param>
/// <exception cref="ArgumentNullException"></exception>
public IHasCamerasMessenger(string key, string messagePath, IHasCameras cameraController)
public IHasCamerasMessenger(string key, string messagePath , IHasCameras cameraController)
: base(key, messagePath, cameraController)
{
CameraController = cameraController ?? throw new ArgumentNullException("cameraController");
@@ -46,9 +49,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, context) => SendFullStatus(id));
AddAction("/cameraListStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, context) =>
{
SendFullStatus(id);
});
AddAction("/selectCamera", (id, content) =>
{

View File

@@ -1,137 +0,0 @@
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Cameras;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Messenger for devices that implement the IHasCameras interface.
/// </summary>
public class IHasCamerasWithControlMessenger : MessengerBase
{
/// <summary>
/// Device being bridged that implements IHasCameras interface.
/// </summary>
public IHasCamerasWithControls CameraController { get; private set; }
/// <summary>
/// Messenger for devices that implement IHasCameras interface.
/// </summary>
/// <param name="key"></param>
/// <param name="cameraController"></param>
/// <param name="messagePath"></param>
/// <exception cref="ArgumentNullException"></exception>
public IHasCamerasWithControlMessenger(string key, string messagePath, IHasCamerasWithControls cameraController)
: base(key, messagePath, cameraController)
{
CameraController = cameraController ?? throw new ArgumentNullException("cameraController");
CameraController.CameraSelected += CameraController_CameraSelected;
}
private void CameraController_CameraSelected(object sender, CameraSelectedEventArgs<IHasCameraControls> e)
{
var selectedCamera = new KeyName
{
Key = e.SelectedCamera.Key,
Name = e.SelectedCamera.Name
};
PostStatusMessage(new IHasCamerasWithControlsStateMessage
{
SelectedCamera = selectedCamera
});
}
/// <summary>
/// Registers the actions for this messenger.
/// </summary>
/// <exception cref="ArgumentException"></exception>
protected override void RegisterActions()
{
base.RegisterActions();
AddAction("/fullStatus", (id, context) => SendFullStatus(id));
AddAction("/cameraListStatus", (id, content) => SendFullStatus(id));
AddAction("/selectCamera", (id, content) =>
{
var cameraKey = content?.ToObject<string>();
if (!string.IsNullOrEmpty(cameraKey))
{
CameraController.SelectCamera(cameraKey);
}
else
{
throw new ArgumentException("Content must be a string representing the camera key");
}
});
}
private void SendFullStatus(string clientId)
{
var cameraList = new List<IKeyName>();
KeyName selectedCamera = null;
foreach (var cam in CameraController.Cameras)
{
cameraList.Add(new KeyName{
Key = cam.Key,
Name = cam.Name
});
}
if (CameraController.SelectedCamera != null)
{
selectedCamera = new KeyName
{
Key = CameraController.SelectedCamera.Key,
Name = CameraController.SelectedCamera.Name
};
}
var state = new IHasCamerasWithControlsStateMessage
{
CameraList = cameraList,
SelectedCamera = selectedCamera
};
PostStatusMessage(state, clientId);
}
}
/// <summary>
/// State message for devices that implement the IHasCameras interface.
/// </summary>
public class IHasCamerasWithControlsStateMessage : DeviceStateMessageBase
{
/// <summary>
/// List of cameras available in the device.
/// </summary>
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
public List<IKeyName> CameraList { get; set; }
/// <summary>
/// The currently selected camera on the device.
/// </summary>
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
public IKeyName SelectedCamera { get; set; }
}
class KeyName : IKeyName
{
public string Key { get; set; }
public string Name { get; set; }
public KeyName()
{
Key = "";
Name = "";
}
}
}

View File

@@ -11,7 +11,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
public class IHasCurrentSourceInfoMessenger : MessengerBase
{
private readonly IHasCurrentSourceInfoChange sourceDevice;
public IHasCurrentSourceInfoMessenger(string key, string messagePath, IHasCurrentSourceInfoChange device) : base(key, messagePath, device as IKeyName)
{
sourceDevice = device;
@@ -21,9 +20,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) =>
{
var message = new CurrentSourceStateMessage
{
CurrentSourceKey = sourceDevice.CurrentSourceInfoKey,
CurrentSource = sourceDevice.CurrentSourceInfo
};
AddAction("/currentSourceInfoStatus", (id, content) => SendFullStatus(id));
PostStatusMessage(message);
});
sourceDevice.CurrentSourceChange += (sender, e) =>
{
@@ -41,17 +47,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
};
}
private void SendFullStatus(string id = null)
{
var message = new CurrentSourceStateMessage
{
CurrentSourceKey = sourceDevice.CurrentSourceInfoKey,
CurrentSource = sourceDevice.CurrentSourceInfo
};
PostStatusMessage(message, id);
}
}
/// <summary>

View File

@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -11,8 +11,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// Represents a IHasInputsMessenger
/// </summary>
public class IHasInputsMessenger<TKey> : MessengerBase
{
private readonly IHasInputs<TKey> itemDevice;
{
private readonly IHasInputs<TKey> itemDevice;
/// <summary>
@@ -23,16 +23,17 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <param name="device"></param>
public IHasInputsMessenger(string key, string messagePath, IHasInputs<TKey> device) : base(key, messagePath, device)
{
itemDevice = device;
itemDevice = device;
}
protected override void RegisterActions()
{
base.RegisterActions();
AddAction("/fullStatus", (id, context) => SendFullStatus(id));
AddAction("/inputStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, context) =>
{
SendFullStatus();
});
itemDevice.Inputs.ItemsUpdated += (sender, args) =>
{
@@ -61,7 +62,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
try
{
@@ -76,7 +77,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
};
PostStatusMessage(stateObject, id);
PostStatusMessage(stateObject);
}
catch (Exception e)
{

View File

@@ -12,12 +12,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
private readonly IHasPowerControlWithFeedback _powerControl;
/// <summary>
/// Initializes a new instance of the <see cref="IHasPowerControlWithFeedbackMessenger"/> class.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="messagePath">The message path.</param>
/// <param name="powerControl">The power control device</param>
public IHasPowerControlWithFeedbackMessenger(string key, string messagePath, IHasPowerControlWithFeedback powerControl)
: base(key, messagePath, powerControl as IKeyName)
{
@@ -27,24 +21,21 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary>
/// SendFullStatus method
/// </summary>
public void SendFullStatus(string id = null)
public void SendFullStatus()
{
var messageObj = new PowerControlWithFeedbackStateMessage
{
PowerState = _powerControl.PowerIsOnFeedback.BoolValue
};
PostStatusMessage(messageObj, id);
PostStatusMessage(messageObj);
}
/// <inheritdoc />
protected override void RegisterActions()
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/powerStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
_powerControl.PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange; ;
}
@@ -64,9 +55,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class PowerControlWithFeedbackStateMessage : DeviceStateMessageBase
{
/// <summary>
/// Power State
/// </summary>
[JsonProperty("powerState", NullValueHandling = NullValueHandling.Ignore)]
public bool? PowerState { get; set; }
}

View File

@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.Codec;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -27,9 +27,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
protected override void RegisterActions()
{
AddAction("/schedule/fullStatus", (id, content) => SendFullScheduleObject(id));
AddAction("/schedule/status", (id, content) => SendFullScheduleObject(id));
AddAction("/schedule/fullStatus", (id, content) => SendFullScheduleObject());
}
private void CodecSchedule_MeetingEventChange(object sender, MeetingEventArgs e)
@@ -53,13 +51,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary>
/// Helper method to send the full schedule data
/// </summary>
private void SendFullScheduleObject(string id = null)
private void SendFullScheduleObject()
{
PostStatusMessage(new FullScheduleMessage
{
Meetings = ScheduleSource.CodecSchedule.Meetings,
MeetingWarningMinutes = ScheduleSource.CodecSchedule.MeetingWarningMinutes
}, id);
});
}
}
@@ -68,18 +66,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class FullScheduleMessage : DeviceStateMessageBase
{
[JsonProperty("meetings", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Meetings
/// </summary>
[JsonProperty("meetings", NullValueHandling = NullValueHandling.Ignore)]
public List<Meeting> Meetings { get; set; }
[JsonProperty("meetingWarningMinutes", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the MeetingWarningMinutes
/// </summary>
[JsonProperty("meetingWarningMinutes", NullValueHandling = NullValueHandling.Ignore)]
public int MeetingWarningMinutes { get; set; }
}
@@ -88,11 +84,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class MeetingChangeMessage
{
[JsonProperty("meetingChange", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the MeetingChange
/// </summary>
[JsonProperty("meetingChange", NullValueHandling = NullValueHandling.Ignore)]
public MeetingChange MeetingChange { get; set; }
}
@@ -101,18 +96,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class MeetingChange
{
[JsonProperty("changeType", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the ChangeType
/// </summary>
[JsonProperty("changeType", NullValueHandling = NullValueHandling.Ignore)]
public string ChangeType { get; set; }
[JsonProperty("meeting", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Meeting
/// </summary>
[JsonProperty("meeting", NullValueHandling = NullValueHandling.Ignore)]
public Meeting Meeting { get; set; }
}
}

View File

@@ -1,7 +1,7 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -22,21 +22,19 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/humidityStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
device.HumidityFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
var state = new IHumiditySensorStateMessage
{
Humidity = string.Format("{0}%", device.HumidityFeedback.UShortValue)
};
PostStatusMessage(state, id);
PostStatusMessage(state);
}
}
@@ -45,11 +43,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class IHumiditySensorStateMessage : DeviceStateMessageBase
{
[JsonProperty("humidity")]
/// <summary>
/// Gets or sets the Humidity
/// </summary>
[JsonProperty("humidity")]
public string Humidity { get; set; }
}
}

View File

@@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -13,7 +13,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
public class ILevelControlsMessenger : MessengerBase
{
private ILevelControls levelControlsDevice;
public ILevelControlsMessenger(string key, string messagePath, ILevelControls device) : base(key, messagePath, device as IKeyName)
{
levelControlsDevice = device;
@@ -23,9 +22,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, context) => SendFullStatus(id));
AddAction("/fullStatus", (id, context) =>
{
var message = new LevelControlStateMessage
{
Levels = levelControlsDevice.LevelControlPoints.ToDictionary(kv => kv.Key, kv => new Volume { Level = kv.Value.VolumeLevelFeedback.IntValue, Muted = kv.Value.MuteFeedback.BoolValue })
};
AddAction("/levelStats", (id, content) => SendFullStatus(id));
PostStatusMessage(message);
});
foreach (var levelControl in levelControlsDevice.LevelControlPoints)
{
@@ -70,16 +75,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
}));
}
}
private void SendFullStatus(string id = null)
{
var message = new LevelControlStateMessage
{
Levels = levelControlsDevice.LevelControlPoints.ToDictionary(kv => kv.Key, kv => new Volume { Level = kv.Value.VolumeLevelFeedback.IntValue, Muted = kv.Value.MuteFeedback.BoolValue })
};
PostStatusMessage(message, id);
}
}
/// <summary>

View File

@@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Routing;
using Serilog.Events;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -25,9 +25,25 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) =>
{
try
{
Debug.LogMessage(LogEventLevel.Verbose, "InputCount: {inputCount}, OutputCount: {outputCount}", this, matrixDevice.InputSlots.Count, matrixDevice.OutputSlots.Count);
var message = new MatrixStateMessage
{
Outputs = matrixDevice.OutputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingOutput(kvp.Value)),
Inputs = matrixDevice.InputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingInput(kvp.Value)),
};
AddAction("/matrixStatus", (id, content) => SendFullStatus(id));
PostStatusMessage(message);
}
catch (Exception e)
{
Debug.LogMessage(e, "Exception Getting full status: {@exception}", this, e);
}
});
AddAction("/route", (id, content) =>
{
@@ -64,26 +80,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
};
}
}
private void SendFullStatus(string id = null)
{
try
{
Debug.LogMessage(LogEventLevel.Verbose, "InputCount: {inputCount}, OutputCount: {outputCount}", this, matrixDevice.InputSlots.Count, matrixDevice.OutputSlots.Count);
var message = new MatrixStateMessage
{
Outputs = matrixDevice.OutputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingOutput(kvp.Value)),
Inputs = matrixDevice.InputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingInput(kvp.Value)),
};
PostStatusMessage(message, id);
}
catch (Exception e)
{
Debug.LogMessage(e, "Exception Getting full status: {@exception}", this, e);
}
}
}
/// <summary>

View File

@@ -1,9 +1,9 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -14,28 +14,17 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
private readonly IProjectorScreenLiftControl device;
/// <summary>
/// Initializes a new instance of the <see cref="IProjectorScreenLiftControlMessenger"/> class.
/// </summary>
/// <param name="key">message key</param>
/// <param name="messagePath">message path</param>
/// <param name="screenLiftDevice">screen lift device</param>
public IProjectorScreenLiftControlMessenger(string key, string messagePath, IProjectorScreenLiftControl screenLiftDevice)
: base(key, messagePath, screenLiftDevice as IKeyName)
{
device = screenLiftDevice;
}
/// <summary>
/// Registers the actions for the messenger.
/// </summary>
protected override void RegisterActions()
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/screenliftStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/raise", (id, content) =>
{
@@ -64,7 +53,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostStatusMessage(JToken.FromObject(state));
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
var state = new ScreenLiftStateMessage
{
@@ -73,7 +62,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
DisplayDeviceKey = device.DisplayDeviceKey
};
PostStatusMessage(state, id);
PostStatusMessage(state);
}
}
@@ -82,23 +71,20 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class ScreenLiftStateMessage : DeviceStateMessageBase
{
/// <summary>
/// Gets or sets the InUpPosition
/// </summary>
[JsonProperty("inUpPosition", NullValueHandling = NullValueHandling.Ignore)]
public bool? InUpPosition { get; set; }
[JsonProperty("displayDeviceKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the DisplayDeviceKey
/// </summary>
[JsonProperty("displayDeviceKey", NullValueHandling = NullValueHandling.Ignore)]
public string DisplayDeviceKey { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Type
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
public eScreenLiftControlType Type { get; set; }
}
}

View File

@@ -1,8 +1,8 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core;
using System;
namespace PepperDash.Essentials.AppServer.Messengers
@@ -36,9 +36,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
protected override void RegisterActions()
{
AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject(id));
AddAction("/routingStatus", (id, content) => SendRoutingFullMessageObject(id));
AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject());
AddAction("/source", (id, content) =>
{
@@ -64,7 +62,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary>
/// Helper method to update full status of the routing device
/// </summary>
private void SendRoutingFullMessageObject(string id = null)
private void SendRoutingFullMessageObject()
{
if (RoutingDevice is IRoutingSink sinkDevice)
{
@@ -86,10 +84,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class RoutingStateMessage : DeviceStateMessageBase
{
[JsonProperty("selectedSourceKey")]
/// <summary>
/// Gets or sets the SelectedSourceKey
/// </summary>
[JsonProperty("selectedSourceKey")]
public string SelectedSourceKey { get; set; }
}
}

View File

@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -11,13 +11,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// Represents a ISelectableItemsMessenger
/// </summary>
public class ISelectableItemsMessenger<TKey> : MessengerBase
{
{
private readonly ISelectableItems<TKey> itemDevice;
private readonly string _propName;
private List<string> _itemKeys = new List<string>();
/// <summary>
/// Constructs a messenger for a device that implements ISelectableItems<typeparamref name="TKey"/>
/// </summary>
@@ -36,40 +34,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
base.RegisterActions();
AddAction("/fullStatus", (id, context) =>
SendFullStatus(id)
);
AddAction("/itemsStatus", (id, content) => SendFullStatus(id));
AddAction("/selectItem", (id, content) =>
{
try
{
var key = content.ToObject<TKey>();
if (key == null)
{
this.LogError("No key specified to select");
return;
}
if (itemDevice.Items.ContainsKey((TKey)Convert.ChangeType(key, typeof(TKey))))
{
itemDevice.Items[(TKey)Convert.ChangeType(key, typeof(TKey))].Select();
}
else
{
this.LogError("Key {0} not found in items", key);
}
}
catch (Exception e)
{
this.LogError("Error selecting item: {0}", e.Message);
}
SendFullStatus();
});
itemDevice.ItemsUpdated += (sender, args) =>
{
SetItems();
SendFullStatus();
};
itemDevice.CurrentItemChanged += (sender, args) =>
@@ -77,48 +48,24 @@ namespace PepperDash.Essentials.AppServer.Messengers
SendFullStatus();
};
SetItems();
}
/// <summary>
/// Sets the items and registers their update events
/// </summary>
private void SetItems()
{
if (_itemKeys != null && _itemKeys.Count > 0)
foreach (var input in itemDevice.Items)
{
/// Clear out any existing item actions
foreach (var item in _itemKeys)
{
RemoveAction($"/{item}");
}
_itemKeys.Clear();
}
foreach (var item in itemDevice.Items)
{
var key = item.Key;
var localItem = item.Value;
var key = input.Key;
var localItem = input.Value;
AddAction($"/{key}", (id, content) =>
{
localItem.Select();
});
_itemKeys.Add(key.ToString());
localItem.ItemUpdated -= LocalItem_ItemUpdated;
localItem.ItemUpdated += LocalItem_ItemUpdated;
localItem.ItemUpdated += (sender, args) =>
{
SendFullStatus();
};
}
}
private void LocalItem_ItemUpdated(object sender, EventArgs e)
{
SendFullStatus();
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
try
{
@@ -130,7 +77,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
CurrentItem = itemDevice.CurrentItem
};
PostStatusMessage(stateObject, id);
PostStatusMessage(stateObject);
}
catch (Exception e)
{
@@ -144,17 +91,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class ISelectableItemsStateMessage<TKey> : DeviceStateMessageBase
{
/// <summary>
/// Gets or sets the Items
/// </summary>
[JsonProperty("items")]
public Dictionary<TKey, ISelectableItem> Items { get; set; }
[JsonProperty("currentItem")]
/// <summary>
/// Gets or sets the CurrentItem
/// </summary>
[JsonProperty("currentItem")]
public TKey CurrentItem { get; set; }
}

View File

@@ -20,9 +20,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
protected override void RegisterActions()
{
AddAction("/status", (id, content) => SendFullStatus(id));
AddAction("/shutdownPromptStatus", (id, content) => SendFullStatus(id));
AddAction("/status", (id, content) =>
{
SendFullStatus();
});
AddAction("/setShutdownPromptSeconds", (id, content) =>
{
@@ -67,7 +68,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
};
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
var status = new IShutdownPromptTimerStateMessage
{
@@ -76,7 +77,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
PercentageRemaining = _room.ShutdownPromptTimer.PercentFeedback.UShortValue
};
PostStatusMessage(status, id);
PostStatusMessage(status);
}
}
@@ -86,22 +87,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class IShutdownPromptTimerStateMessage : DeviceStateMessageBase
{
[JsonProperty("secondsRemaining")]
/// <summary>
/// Gets or sets the SecondsRemaining
/// </summary>
[JsonProperty("secondsRemaining")]
public int SecondsRemaining { get; set; }
[JsonProperty("percentageRemaining")]
/// <summary>
/// Gets or sets the PercentageRemaining
/// </summary>
[JsonProperty("percentageRemaining")]
public int PercentageRemaining { get; set; }
[JsonProperty("shutdownPromptSeconds")]
/// <summary>
/// Gets or sets the ShutdownPromptSeconds
/// </summary>
[JsonProperty("shutdownPromptSeconds")]
public int ShutdownPromptSeconds { get; set; }
}
}

View File

@@ -1,7 +1,7 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.CrestronIO;
using System;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -23,9 +23,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/switchedOutputStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/on", (id, content) =>
{
@@ -44,14 +42,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
device.OutputIsOnFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
var state = new ISwitchedOutputStateMessage
{
IsOn = device.OutputIsOnFeedback.BoolValue
};
PostStatusMessage(state, id);
PostStatusMessage(state);
}
}
@@ -60,10 +58,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class ISwitchedOutputStateMessage : DeviceStateMessageBase
{
[JsonProperty("isOn")]
/// <summary>
/// Gets or sets the IsOn
/// </summary>
[JsonProperty("isOn")]
public bool IsOn { get; set; }
}
}

View File

@@ -20,9 +20,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
protected override void RegisterActions()
{
AddAction("/status", (id, content) => SendFullStatus(id));
AddAction("/techPasswordStatus", (id, content) => SendFullStatus(id));
AddAction("/status", (id, content) =>
{
SendFullStatus();
});
AddAction("/validateTechPassword", (id, content) =>
{
@@ -54,14 +55,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
};
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
var status = new ITechPasswordStateMessage
{
TechPasswordLength = _room.TechPasswordLength
};
PostStatusMessage(status, id);
PostStatusMessage(status);
}
}

View File

@@ -1,7 +1,7 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -22,9 +22,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/temperatureStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/setTemperatureUnitsToCelcius", (id, content) =>
{
@@ -40,7 +38,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
device.TemperatureInCFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
// format the temperature to a string with one decimal place
var tempString = string.Format("{0}.{1}", device.TemperatureFeedback.UShortValue / 10, device.TemperatureFeedback.UShortValue % 10);
@@ -51,7 +49,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
TemperatureInCelsius = device.TemperatureInCFeedback.BoolValue
};
PostStatusMessage(state, id);
PostStatusMessage(state);
}
}
@@ -60,16 +58,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class ITemperatureSensorStateMessage : DeviceStateMessageBase
{
[JsonProperty("temperature")]
/// <summary>
/// Gets or sets the Temperature
/// </summary>
[JsonProperty("temperature")]
public string Temperature { get; set; }
[JsonProperty("temperatureInCelsius")]
/// <summary>
/// Gets or sets the TemperatureInCelsius
/// </summary>
[JsonProperty("temperatureInCelsius")]
public bool TemperatureInCelsius { get; set; }
}
}

View File

@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Lighting;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -35,9 +35,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/lightingStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/selectScene", (id, content) =>
{
@@ -45,14 +43,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
lightingScenesDevice.SelectScene(s);
});
if (!(lightingScenesDevice is ILightingScenesDynamic lightingScenesDynamic))
if(!(lightingScenesDevice is ILightingScenesDynamic lightingScenesDynamic))
return;
lightingScenesDynamic.LightingScenesUpdated += (s, e) => SendFullStatus();
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
var state = new LightingBaseStateMessage
{
@@ -60,7 +58,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
CurrentLightingScene = lightingScenesDevice.CurrentLightingScene
};
PostStatusMessage(state, id);
PostStatusMessage(state);
}
}
@@ -69,17 +67,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class LightingBaseStateMessage : DeviceStateMessageBase
{
[JsonProperty("scenes", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Scenes
/// </summary>
[JsonProperty("scenes", NullValueHandling = NullValueHandling.Ignore)]
public List<LightingScene> Scenes { get; set; }
[JsonProperty("currentLightingScene", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the CurrentLightingScene
/// </summary>
[JsonProperty("currentLightingScene", NullValueHandling = NullValueHandling.Ignore)]
public LightingScene CurrentLightingScene { get; set; }
}
}

View File

@@ -1,45 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Provides a messaging bridge
/// </summary>
public abstract class MessengerBase : EssentialsDevice, IMobileControlMessengerWithSubscriptions
public abstract class MessengerBase : EssentialsDevice, IMobileControlMessenger
{
/// <summary>
/// The device this messenger is associated with
/// </summary>
protected IKeyName _device;
/// <summary>
/// Enable subscriptions
/// </summary>
protected bool enableMessengerSubscriptions;
/// <summary>
/// List of clients subscribed to this messenger
/// </summary>
/// <remarks>
/// Unsoliciited feedback from a device in a messenger will ONLY be sent to devices in this subscription list. When a client disconnects, it's ID will be removed from the collection.
/// </remarks>
protected HashSet<string> SubscriberIds = new HashSet<string>();
private readonly List<string> _deviceInterfaces;
private readonly Dictionary<string, Action<string, JToken>> _actions = new Dictionary<string, Action<string, JToken>>();
/// <summary>
/// Gets the DeviceKey
/// </summary>
public string DeviceKey => _device?.Key ?? "";
@@ -69,12 +50,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
MessagePath = messagePath;
}
/// <summary>
/// Constructor for a messenger associated with a device
/// </summary>
/// <param name="key"></param>
/// <param name="messagePath"></param>
/// <param name="device"></param>
protected MessengerBase(string key, string messagePath, IKeyName device)
: this(key, messagePath)
{
@@ -106,21 +81,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
RegisterActions();
}
/// <summary>
/// Register this messenger with appserver controller
/// </summary>
/// <param name="appServerController">Parent controller for this messenger</param>
/// <param name="enableMessengerSubscriptions">Enable subscriptions</param>
public void RegisterWithAppServer(IMobileControl appServerController, bool enableMessengerSubscriptions)
{
this.enableMessengerSubscriptions = enableMessengerSubscriptions;
AppServerController = appServerController ?? throw new ArgumentNullException("appServerController");
AppServerController.AddAction(this, HandleMessage);
RegisterActions();
}
private void HandleMessage(string path, string id, JToken content)
{
// replace base path with empty string. Should leave something like /fullStatus
@@ -131,20 +91,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
return;
}
this.LogDebug("Executing action for path {path}", path);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Executing action for path {path}", this, path);
action(id, content);
}
/// <summary>
/// Adds an action for a given path
/// </summary>
/// <param name="path"></param>
/// <param name="action"></param>
protected void AddAction(string path, Action<string, JToken> action)
{
if (_actions.ContainsKey(path))
{
//Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, $"Messenger {Key} already has action registered at {path}", this);
return;
}
@@ -159,10 +115,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
return _actions.Keys.ToList();
}
/// <summary>
/// Removes an action for a given path
/// </summary>
/// <param name="path"></param>
protected void RemoveAction(string path)
{
if (!_actions.ContainsKey(path))
@@ -176,62 +128,17 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary>
/// Implemented in extending classes. Wire up API calls and feedback here
/// </summary>
/// <param name="appServerController"></param>
protected virtual void RegisterActions()
{
}
/// <summary>
/// Add client to the susbscription list for unsolicited feedback
/// </summary>
/// <param name="clientId">Client ID to add</param>
protected void SubscribeClient(string clientId)
{
if (!enableMessengerSubscriptions)
{
this.LogWarning("Messenger subscriptions not enabled");
return;
}
if (SubscriberIds.Any(id => id == clientId))
{
this.LogVerbose("Client {clientId} already subscribed", clientId);
return;
}
SubscriberIds.Add(clientId);
this.LogDebug("Client {clientId} subscribed", clientId);
}
/// <summary>
/// Remove a client from the subscription list
/// </summary>
/// <param name="clientId">Client ID to remove</param>
public void UnsubscribeClient(string clientId)
{
if (!enableMessengerSubscriptions)
{
this.LogWarning("Messenger subscriptions not enabled");
return;
}
if (!SubscriberIds.Any(i => i == clientId))
{
this.LogVerbose("Client with ID {clientId} is not subscribed", clientId);
return;
}
SubscriberIds.RemoveWhere((i) => i == clientId);
this.LogInformation("Client with ID {clientId} unsubscribed", clientId);
}
/// <summary>
/// Helper for posting status message
/// </summary>
/// <param name="type"></param>
/// <param name="message"></param>
/// <param name="clientId">Optional client id that will direct the message back to only that client</param>
protected void PostStatusMessage(DeviceStateMessageBase message, string clientId = null)
{
try
@@ -252,22 +159,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
message.Name = _device.Name;
var token = JToken.FromObject(message);
var token = JToken.FromObject(message);
PostStatusMessage(token, MessagePath, clientId);
}
catch (Exception ex)
{
this.LogError(ex, "Exception posting status message for {messagePath} to {clientId}", MessagePath, clientId ?? "all clients");
this.LogError(ex, "Exception posting status message for {messagePath} to {clientId}", MessagePath, clientId ?? "all clients");
}
}
/// <summary>
/// Helper for posting status message
/// </summary>
/// <param name="type"></param>
/// <param name="deviceState"></param>
/// <param name="clientId">Optional client id that will direct the message back to only that client</param>
protected void PostStatusMessage(string type, DeviceStateMessageBase deviceState, string clientId = null)
{
try
@@ -287,54 +188,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
catch (Exception ex)
{
this.LogError(ex, "Exception posting status message for {type} to {clientId}", type, clientId ?? "all clients");
this.LogError(ex, "Exception posting status message for {type} to {clientId}", type, clientId ?? "all clients");
}
}
/// <summary>
/// Helper for posting status message
/// </summary>
/// <param name="content"></param>
/// <param name="type"></param>
/// <param name="clientId">Optional client id that will direct the message back to only that client</param>
protected void PostStatusMessage(JToken content, string type = "", string clientId = null)
{
try
{
// Allow for legacy method to continue without subscriptions
if (!enableMessengerSubscriptions)
{
AppServerController?.SendMessageObject(new MobileControlMessage { Type = !string.IsNullOrEmpty(type) ? type : MessagePath, ClientId = clientId, Content = content });
return;
}
// handle subscription feedback
// If client is null or empty, this message is unsolicited feedback. Iterate through the subscriber list and send to all interested parties
if (string.IsNullOrEmpty(clientId))
{
foreach (var client in SubscriberIds)
{
AppServerController?.SendMessageObject(new MobileControlMessage { Type = !string.IsNullOrEmpty(type) ? type : MessagePath, ClientId = client, Content = content });
}
return;
}
SubscribeClient(clientId);
AppServerController?.SendMessageObject(new MobileControlMessage { Type = !string.IsNullOrEmpty(type) ? type : MessagePath, ClientId = clientId, Content = content });
}
catch (Exception ex)
{
this.LogError("Exception posting status message: {message}", ex.Message);
this.LogDebug(ex, "Stack Trace: ");
Debug.LogMessage(ex, "Exception posting status message", this);
}
}
/// <summary>
/// Helper for posting event message
/// </summary>
/// <param name="message"></param>
protected void PostEventMessage(DeviceEventMessageBase message)
{
message.Key = _device.Key;
@@ -348,11 +217,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
});
}
/// <summary>
/// Helper for posting event message
/// </summary>
/// <param name="message"></param>
/// <param name="eventType"></param>
protected void PostEventMessage(DeviceEventMessageBase message, string eventType)
{
message.Key = _device.Key;
@@ -368,10 +232,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
});
}
/// <summary>
/// Helper for posting event message with no content
/// </summary>
/// <param name="eventType"></param>
protected void PostEventMessage(string eventType)
{
AppServerController?.SendMessageObject(new MobileControlMessage
@@ -382,4 +242,64 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
}
}
public abstract class DeviceMessageBase
{
/// <summary>
/// The device key
/// </summary>
[JsonProperty("key")]
/// <summary>
/// Gets or sets the Key
/// </summary>
public string Key { get; set; }
/// <summary>
/// The device name
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// The type of the message class
/// </summary>
[JsonProperty("messageType")]
public string MessageType => GetType().Name;
[JsonProperty("messageBasePath")]
/// <summary>
/// Gets or sets the MessageBasePath
/// </summary>
public string MessageBasePath { get; set; }
}
/// <summary>
/// Represents a DeviceStateMessageBase
/// </summary>
public class DeviceStateMessageBase : DeviceMessageBase
{
/// <summary>
/// The interfaces implmented by the device sending the messsage
/// </summary>
[JsonProperty("interfaces")]
public List<string> Interfaces { get; private set; }
public void SetInterfaces(List<string> interfaces)
{
Interfaces = interfaces;
}
}
/// <summary>
/// Base class for event messages that include the type of message and an event type
/// </summary>
public abstract class DeviceEventMessageBase : DeviceMessageBase
{
/// <summary>
/// The event type
/// </summary>
[JsonProperty("eventType")]
public string EventType { get; set; }
}
}

View File

@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharp;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Handler for press/hold/release messages
/// </summary>
public static class PressAndHoldHandler
{
private const long ButtonHeartbeatInterval = 1000;
@@ -29,21 +26,21 @@ namespace PepperDash.Essentials.AppServer.Messengers
private static void AddTimer(string deviceKey, Action<bool> action)
{
Debug.LogDebug("Attempting to add timer for {deviceKey}", deviceKey);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Attempting to add timer for {deviceKey}", deviceKey);
if (_pushedActions.TryGetValue(deviceKey, out CTimer cancelTimer))
{
Debug.LogDebug("Timer for {deviceKey} already exists", deviceKey);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Timer for {deviceKey} already exists", deviceKey);
return;
}
Debug.LogDebug("Adding timer for {deviceKey} with due time {dueTime}", deviceKey, ButtonHeartbeatInterval);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Adding timer for {deviceKey} with due time {dueTime}", deviceKey, ButtonHeartbeatInterval);
action(true);
cancelTimer = new CTimer(o =>
{
Debug.LogDebug("Timer expired for {deviceKey}", deviceKey);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Timer expired for {deviceKey}", deviceKey);
action(false);
@@ -55,30 +52,30 @@ namespace PepperDash.Essentials.AppServer.Messengers
private static void ResetTimer(string deviceKey, Action<bool> action)
{
Debug.LogDebug("Attempting to reset timer for {deviceKey}", deviceKey);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Attempting to reset timer for {deviceKey}", deviceKey);
if (!_pushedActions.TryGetValue(deviceKey, out CTimer cancelTimer))
{
Debug.LogDebug("Timer for {deviceKey} not found", deviceKey);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Timer for {deviceKey} not found", deviceKey);
return;
}
Debug.LogDebug("Resetting timer for {deviceKey} with due time {dueTime}", deviceKey, ButtonHeartbeatInterval);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Resetting timer for {deviceKey} with due time {dueTime}", deviceKey, ButtonHeartbeatInterval);
cancelTimer.Reset(ButtonHeartbeatInterval);
}
private static void StopTimer(string deviceKey, Action<bool> action)
{
Debug.LogDebug("Attempting to stop timer for {deviceKey}", deviceKey);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Attempting to stop timer for {deviceKey}", deviceKey);
if (!_pushedActions.TryGetValue(deviceKey, out CTimer cancelTimer))
{
Debug.LogDebug("Timer for {deviceKey} not found", deviceKey);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Timer for {deviceKey} not found", deviceKey);
return;
}
Debug.LogDebug("Stopping timer for {deviceKey} with due time {dueTime}", deviceKey, ButtonHeartbeatInterval);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Stopping timer for {deviceKey} with due time {dueTime}", deviceKey, ButtonHeartbeatInterval);
action(false);
cancelTimer.Stop();
@@ -87,15 +84,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
public static Action<string, Action<bool>> GetPressAndHoldHandler(string value)
{
Debug.LogDebug("Getting press and hold handler for {value}", value);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Getting press and hold handler for {value}", value);
if (!_pushedActionHandlers.TryGetValue(value, out Action<string, Action<bool>> handler))
{
Debug.LogDebug("Press and hold handler for {value} not found", value);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Press and hold handler for {value} not found", value);
return null;
}
Debug.LogDebug("Got handler for {value}", value);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Got handler for {value}", value);
return handler;
}
@@ -107,7 +104,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
var msg = content.ToObject<MobileControlSimpleContent<string>>();
Debug.LogDebug("Handling press and hold message of {type} for {deviceKey}", msg.Value, deviceKey);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Handling press and hold message of {type} for {deviceKey}", msg.Value, deviceKey);
var timerHandler = GetPressAndHoldHandler(msg.Value);

View File

@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Room.Config;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -31,14 +31,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
var events = _room.GetScheduledEvents();
SendFullStatus(events, id);
});
AddAction("/scheduledEventsStatus", (id, content) =>
{
var events = _room.GetScheduledEvents();
SendFullStatus(events, id);
SendFullStatus(events);
});
_room.ScheduledEventsChanged += (sender, args) => SendFullStatus(args.ScheduledEvents);
@@ -62,11 +55,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
catch (Exception ex)
{
this.LogException(ex, "Exception saving event");
this.LogException(ex,"Exception saving event");
}
}
private void SendFullStatus(List<ScheduledEventConfig> events, string id = null)
private void SendFullStatus(List<ScheduledEventConfig> events)
{
var message = new RoomEventScheduleStateMessage
@@ -74,7 +67,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
ScheduleEvents = events,
};
PostStatusMessage(message, id);
PostStatusMessage(message);
}
}

View File

@@ -1,7 +1,7 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Shades;
using System;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -22,8 +22,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/shadesStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/shadeUp", (id, content) =>
{
@@ -76,7 +75,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
private void SendFullStatus(string id = null)
private void SendFullStatus()
{
var state = new ShadeBaseStateMessage();
@@ -86,7 +85,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
state.IsClosed = feedbackDevice.ShadeIsClosedFeedback.BoolValue;
}
PostStatusMessage(state, id);
PostStatusMessage(state);
}
}
@@ -95,11 +94,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class ShadeBaseStateMessage : DeviceStateMessageBase
{
[JsonProperty("middleButtonLabel", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the MiddleButtonLabel
/// </summary>
[JsonProperty("middleButtonLabel", NullValueHandling = NullValueHandling.Ignore)]
public string MiddleButtonLabel { get; set; }
[JsonProperty("isOpen", NullValueHandling = NullValueHandling.Ignore)]

View File

@@ -1,10 +1,10 @@
using System;
using System.Threading.Tasks;
using Crestron.SimplSharp;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core.Monitoring;
using System;
using System.Threading.Tasks;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -56,37 +56,36 @@ namespace PepperDash.Essentials.AppServer.Messengers
SendSystemMonitorStatusMessage();
}
private void SendFullStatusMessage(string id = null)
private void SendFullStatusMessage()
{
SendSystemMonitorStatusMessage(id);
SendSystemMonitorStatusMessage();
foreach (var p in systemMonitor.ProgramStatusFeedbackCollection)
{
PostStatusMessage(JToken.FromObject(p.Value.ProgramInfo), id);
PostStatusMessage(JToken.FromObject(p.Value.ProgramInfo));
}
}
private void SendSystemMonitorStatusMessage(string id = null)
private void SendSystemMonitorStatusMessage()
{
// This takes a while, launch a new thread
Task.Run(() => PostStatusMessage(JToken.FromObject(new SystemMonitorStateMessage
{
TimeZone = systemMonitor.TimeZoneFeedback.IntValue,
TimeZoneName = systemMonitor.TimeZoneTextFeedback.StringValue,
IoControllerVersion = systemMonitor.IoControllerVersionFeedback.StringValue,
SnmpVersion = systemMonitor.SnmpVersionFeedback.StringValue,
BacnetVersion = systemMonitor.BaCnetAppVersionFeedback.StringValue,
ControllerVersion = systemMonitor.ControllerVersionFeedback.StringValue
}), id
})
));
}
protected override void RegisterActions()
{
AddAction("/fullStatus", (id, content) => SendFullStatusMessage(id));
AddAction("/systemStatus", (id, content) => SendFullStatusMessage(id));
AddAction("/fullStatus", (id, content) => SendFullStatusMessage());
}
}
@@ -95,45 +94,40 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class SystemMonitorStateMessage
{
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the TimeZone
/// </summary>
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
public int TimeZone { get; set; }
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the TimeZoneName
/// </summary>
[JsonProperty("timeZoneName", NullValueHandling = NullValueHandling.Ignore)]
public string TimeZoneName { get; set; }
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the IoControllerVersion
/// </summary>
[JsonProperty("ioControllerVersion", NullValueHandling = NullValueHandling.Ignore)]
public string IoControllerVersion { get; set; }
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the SnmpVersion
/// </summary>
[JsonProperty("snmpVersion", NullValueHandling = NullValueHandling.Ignore)]
public string SnmpVersion { get; set; }
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the BacnetVersion
/// </summary>
[JsonProperty("bacnetVersion", NullValueHandling = NullValueHandling.Ignore)]
public string BacnetVersion { get; set; }
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the ControllerVersion
/// </summary>
[JsonProperty("controllerVersion", NullValueHandling = NullValueHandling.Ignore)]
public string ControllerVersion { get; set; }
}
}

View File

@@ -23,7 +23,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary>
/// SendFullStatus method
/// </summary>
public void SendFullStatus(string id = null)
public void SendFullStatus()
{
var messageObj = new TwoWayDisplayBaseStateMessage
{
@@ -31,17 +31,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
CurrentInput = _display.CurrentInputFeedback.StringValue
};
PostStatusMessage(messageObj, id);
PostStatusMessage(messageObj);
}
protected override void RegisterActions()
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/displayStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
//_display.PowerIsOnFeedback.OutputChange += PowerIsOnFeedbackOnOutputChange;
_display.CurrentInputFeedback.OutputChange += CurrentInputFeedbackOnOutputChange;
_display.IsCoolingDownFeedback.OutputChange += IsCoolingFeedbackOnOutputChange;
_display.IsWarmingUpFeedback.OutputChange += IsWarmingFeedbackOnOutputChange;
@@ -56,6 +55,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
);
}
//private void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
//{
// PostStatusMessage(JToken.FromObject(new
// {
// powerState = feedbackEventArgs.BoolValue
// })
// );
//}
private void IsWarmingFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
{
PostStatusMessage(JToken.FromObject(new
@@ -87,11 +96,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
//[JsonProperty("powerState", NullValueHandling = NullValueHandling.Ignore)]
//public bool? PowerState { get; set; }
[JsonProperty("currentInput", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the CurrentInput
/// </summary>
[JsonProperty("currentInput", NullValueHandling = NullValueHandling.Ignore)]
public string CurrentInput { get; set; }
}
}

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Crestron.SimplSharp;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
@@ -13,6 +9,9 @@ using PepperDash.Essentials.Devices.Common.Cameras;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -152,8 +151,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostStatusMessage(state);
SendFullStatus();
}
catch (Exception ex)
} catch (Exception ex)
{
this.LogError(ex, "Error sending codec ready status");
}
@@ -171,8 +169,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
AddAction("/isReady", (id, content) => SendIsReady());
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/codecStatus", (id, content) => SendFullStatus(id));
AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/dial", (id, content) =>
{
@@ -372,8 +369,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
};
PostStatusMessage(state);
}
catch (Exception ex)
} catch (Exception ex)
{
this.LogError(ex, "Error posting sharing source");
}
@@ -389,8 +385,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
};
PostStatusMessage(state);
}
catch (Exception ex)
} catch (Exception ex)
{
this.LogError(ex, "Error posting sharing content");
}
@@ -440,8 +435,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
MapCameraActions();
PostSelectedCamera();
}
catch (Exception ex)
} catch(Exception ex)
{
this.LogError(ex, "Exception handling camera selected event");
}
@@ -786,14 +780,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
}
protected virtual void SendFullStatus(string id = null)
protected virtual void SendFullStatus()
{
if (!Codec.IsReady)
{
return;
}
Task.Run(() => PostStatusMessage(GetStatus(), id));
CrestronInvoke.BeginInvoke((o) => PostStatusMessage(GetStatus()));
}
private void PostReceivingContent(bool receivingContent)
@@ -806,8 +800,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
};
PostStatusMessage(state);
}
catch (Exception ex)
} catch(Exception ex)
{
this.LogError(ex, "Error posting receiving content");
}
@@ -956,25 +949,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
[JsonProperty("cameraSupportsOffMode", NullValueHandling = NullValueHandling.Ignore)]
public bool? CameraSupportsOffMode { get; set; }
[JsonProperty("currentDialString", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the CurrentDialString
/// </summary>
[JsonProperty("currentDialString", NullValueHandling = NullValueHandling.Ignore)]
public string CurrentDialString { get; set; }
[JsonProperty("currentDirectory", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the CurrentDirectory
/// </summary>
[JsonProperty("currentDirectory", NullValueHandling = NullValueHandling.Ignore)]
public CodecDirectory CurrentDirectory { get; set; }
[JsonProperty("directorySelectedFolderName", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the DirectorySelectedFolderName
/// </summary>
[JsonProperty("directorySelectedFolderName", NullValueHandling = NullValueHandling.Ignore)]
public string DirectorySelectedFolderName { get; set; }
[JsonProperty("hasCameras", NullValueHandling = NullValueHandling.Ignore)]
@@ -995,11 +985,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
[JsonProperty("initialPhonebookSyncComplete", NullValueHandling = NullValueHandling.Ignore)]
public bool? InitialPhonebookSyncComplete { get; set; }
[JsonProperty("info", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Info
/// </summary>
[JsonProperty("info", NullValueHandling = NullValueHandling.Ignore)]
public VideoCodecInfo Info { get; set; }
[JsonProperty("isInCall", NullValueHandling = NullValueHandling.Ignore)]
@@ -1011,18 +1000,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
[JsonProperty("isZoomRoom", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsZoomRoom { get; set; }
[JsonProperty("meetingInfo", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the MeetingInfo
/// </summary>
[JsonProperty("meetingInfo", NullValueHandling = NullValueHandling.Ignore)]
public MeetingInfo MeetingInfo { get; set; }
[JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Presets
/// </summary>
[JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)]
public List<CodecRoomPreset> Presets { get; set; }
[JsonProperty("privacyModeIsOn", NullValueHandling = NullValueHandling.Ignore)]
@@ -1037,11 +1024,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
[JsonProperty("sharingContentIsOn", NullValueHandling = NullValueHandling.Ignore)]
public bool? SharingContentIsOn { get; set; }
[JsonProperty("sharingSource", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the SharingSource
/// </summary>
[JsonProperty("sharingSource", NullValueHandling = NullValueHandling.Ignore)]
public string SharingSource { get; set; }
[JsonProperty("showCamerasWhenNotInCall", NullValueHandling = NullValueHandling.Ignore)]
@@ -1071,26 +1057,23 @@ namespace PepperDash.Essentials.AppServer.Messengers
[JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)]
public bool? CameraOffIsSupported { get; set; }
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the CameraMode
/// </summary>
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
public string CameraMode { get; set; }
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Cameras
/// </summary>
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
public List<CameraBase> Cameras { get; set; }
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the SelectedCamera
/// </summary>
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
public Camera SelectedCamera { get; set; }
public Camera SelectedCamera { get; set; }
}
/// <summary>
@@ -1098,28 +1081,25 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class Camera
{
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Key
/// </summary>
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
public string Key { get; set; }
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Name
/// </summary>
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }
[JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsFarEnd { get; set; }
[JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Capabilities
/// </summary>
[JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)]
public CameraCapabilities Capabilities { get; set; }
}
@@ -1155,31 +1135,27 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary>
public class PasswordPromptEventMessage : VideoCodecBaseEventMessage
{
[JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Message
/// </summary>
[JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)]
public string Message { get; set; }
[JsonProperty("lastAttemptWasIncorrect", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the LastAttemptWasIncorrect
/// </summary>
[JsonProperty("lastAttemptWasIncorrect", NullValueHandling = NullValueHandling.Ignore)]
public bool LastAttemptWasIncorrect { get; set; }
[JsonProperty("loginAttemptFailed", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the LoginAttemptFailed
/// </summary>
[JsonProperty("loginAttemptFailed", NullValueHandling = NullValueHandling.Ignore)]
public bool LoginAttemptFailed { get; set; }
[JsonProperty("loginAttemptCancelled", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the LoginAttemptCancelled
/// </summary>
[JsonProperty("loginAttemptCancelled", NullValueHandling = NullValueHandling.Ignore)]
public bool LoginAttemptCancelled { get; set; }
}
}

View File

@@ -7,18 +7,16 @@ namespace PepperDash.Essentials
/// </summary>
public class AuthorizationResponse
{
[JsonProperty("authorized")]
/// <summary>
/// Gets or sets the Authorized
/// </summary>
[JsonProperty("authorized")]
public bool Authorized { get; set; }
[JsonProperty("reason", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Reason
/// </summary>
[JsonProperty("reason", NullValueHandling = NullValueHandling.Ignore)]
public string Reason { get; set; } = null;
}
@@ -27,11 +25,10 @@ namespace PepperDash.Essentials
/// </summary>
public class AuthorizationRequest
{
[JsonProperty("grantCode")]
/// <summary>
/// Gets or sets the GrantCode
/// </summary>
[JsonProperty("grantCode")]
public string GrantCode { get; set; }
}
}

View File

@@ -1,20 +0,0 @@
using System;
namespace PepperDash.Essentials
{
/// <summary>
/// Represents a ClientSpecificUpdateRequest
/// </summary>
public class ClientSpecificUpdateRequest
{
public ClientSpecificUpdateRequest(Action<string> action)
{
ResponseMethod = action;
}
/// <summary>
/// Gets or sets the ResponseMethod
/// </summary>
public Action<string> ResponseMethod { get; private set; }
}
}

View File

@@ -38,12 +38,6 @@ namespace PepperDash.Essentials
/// </summary>
[JsonProperty("enableApiServer")]
public bool EnableApiServer { get; set; } = true;
/// <summary>
/// Enable subscriptions for Messengers
/// </summary>
[JsonProperty("enableMessengerSubscriptions")]
public bool EnableMessengerSubscriptions { get; set; }
}
/// <summary>
@@ -84,15 +78,6 @@ namespace PepperDash.Essentials
[JsonProperty("csLanUiDeviceKeys")]
public List<string> CSLanUiDeviceKeys { get; set; }
/// <summary>
/// Get or set the Secure property
/// </summary>
/// <remarks>
/// Indicates whether the connection is secure (HTTPS).
/// </remarks>
[JsonProperty("Secure")]
public bool Secure { get; set; }
/// <summary>
/// Initializes a new instance of the MobileControlDirectServerPropertiesConfig class.
/// </summary>

View File

@@ -1,6 +1,6 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Essentials.Core.Config;
using System.Collections.Generic;
namespace PepperDash.Essentials
@@ -39,11 +39,10 @@ namespace PepperDash.Essentials
/// </summary>
public class MobileControlRuntimeInfo
{
[JsonProperty("pluginVersion")]
/// <summary>
/// Gets or sets the PluginVersion
/// </summary>
[JsonProperty("pluginVersion")]
public string PluginVersion { get; set; }
[JsonProperty("essentialsVersion")]
@@ -52,11 +51,10 @@ namespace PepperDash.Essentials
[JsonProperty("pepperDashCoreVersion")]
public string PepperDashCoreVersion { get; set; }
[JsonProperty("essentialsPlugins")]
/// <summary>
/// Gets or sets the EssentialsPlugins
/// </summary>
[JsonProperty("essentialsPlugins")]
public List<LoadedAssembly> EssentialsPlugins { get; set; }
}
}

View File

@@ -54,10 +54,7 @@ namespace PepperDash.Essentials
StringComparer.InvariantCultureIgnoreCase
);
/// <summary>
/// Actions
/// </summary>
public ReadOnlyDictionary<string, List<IMobileControlAction>> ActionDictionary => new ReadOnlyDictionary<string, List<IMobileControlAction>>(_actionDictionary);
public Dictionary<string, List<IMobileControlAction>> ActionDictionary => _actionDictionary;
private readonly GenericQueue _receiveQueue;
private readonly List<MobileControlBridgeBase> _roomBridges =
@@ -69,16 +66,6 @@ namespace PepperDash.Essentials
private readonly Dictionary<string, IMobileControlMessenger> _defaultMessengers =
new Dictionary<string, IMobileControlMessenger>();
/// <summary>
/// Get the custom messengers with subscriptions
/// </summary>
public ReadOnlyDictionary<string, IMobileControlMessengerWithSubscriptions> Messengers => new ReadOnlyDictionary<string, IMobileControlMessengerWithSubscriptions>(_messengers.Values.OfType<IMobileControlMessengerWithSubscriptions>().ToDictionary(k => k.Key, v => v));
/// <summary>
/// Get the default messengers
/// </summary>
public ReadOnlyDictionary<string, IMobileControlMessengerWithSubscriptions> DefaultMessengers => new ReadOnlyDictionary<string, IMobileControlMessengerWithSubscriptions>(_defaultMessengers.Values.OfType<IMobileControlMessengerWithSubscriptions>().ToDictionary(k => k.Key, v => v));
private readonly GenericQueue _transmitToServerQueue;
private readonly GenericQueue _transmitToClientsQueue;
@@ -257,7 +244,7 @@ namespace PepperDash.Essentials
CrestronEnvironment.ProgramStatusEventHandler +=
CrestronEnvironment_ProgramStatusEventHandler;
ApiOnlineAndAuthorized = new BoolFeedback("apiOnlineAndAuthorized", () =>
ApiOnlineAndAuthorized = new BoolFeedback(() =>
{
if (_wsClient2 == null)
return false;
@@ -405,15 +392,14 @@ namespace PepperDash.Essentials
messengerAdded = true;
}
// Default to IHasCameraControls if CameraBase and IHasCameraControls
if (device is CameraBase cameraDevice && !(device is IHasCameraControls))
if (device is CameraBase cameraDevice)
{
this.LogVerbose(
"Adding CameraBaseMessenger for {deviceKey}",
device.Key
);
var cameraMessenger = new CameraBaseMessenger<CameraBase>(
var cameraMessenger = new CameraBaseMessenger(
$"{device.Key}-cameraBase-{Key}",
cameraDevice,
$"/device/{device.Key}"
@@ -424,21 +410,6 @@ namespace PepperDash.Essentials
messengerAdded = true;
}
if (device is IHasCameraControls cameraControlDev)
{
this.LogVerbose(
"Adding IHasCamerasWithControlMessenger for {deviceKey}",
device.Key
);
var cameraControlMessenger = new CameraBaseMessenger<IHasCameraControls>(
$"{device.Key}-hasCamerasWithControls-{Key}",
cameraControlDev,
$"/device/{device.Key}"
);
AddDefaultDeviceMessenger(cameraControlMessenger);
messengerAdded = true;
}
if (device is BlueJeansPc)
{
this.LogVerbose(
@@ -515,15 +486,15 @@ namespace PepperDash.Essentials
messengerAdded = true;
}
if (device is IBasicVolumeControls)
if (device is IBasicVolumeWithFeedback)
{
var deviceKey = device.Key;
this.LogVerbose(
"Adding IBasicVolumeControls for {deviceKey}",
"Adding IBasicVolumeControlWithFeedback for {deviceKey}",
deviceKey
);
var volControlDevice = device as IBasicVolumeControls;
var volControlDevice = device as IBasicVolumeWithFeedback;
var messenger = new DeviceVolumeMessenger(
$"{device.Key}-volume-{Key}",
string.Format("/device/{0}", deviceKey),
@@ -991,19 +962,6 @@ namespace PepperDash.Essentials
messengerAdded = true;
}
if (device is IHasCamerasWithControls cameras2)
{
this.LogVerbose("Adding IHasCamerasWithControlsMessenger for {deviceKey}", device.Key
);
var messenger = new IHasCamerasWithControlMessenger(
$"{device.Key}-cameras-{Key}",
$"/device/{device.Key}",
cameras2
);
AddDefaultDeviceMessenger(messenger);
messengerAdded = true;
}
this.LogVerbose("Trying to cast to generic device for device: {key}", device.Key);
if (device is EssentialsDevice)
@@ -1241,7 +1199,8 @@ namespace PepperDash.Essentials
if (_initialized)
{
RegisterMessengerWithServer(messenger);
this.LogDebug("Registering messenger {messengerKey} AFTER initialization", messenger.Key);
messenger.RegisterWithAppServer(this);
}
}
@@ -1282,12 +1241,6 @@ namespace PepperDash.Essentials
messenger.MessagePath
);
if (messenger is IMobileControlMessengerWithSubscriptions subMessenger)
{
subMessenger.RegisterWithAppServer(this, Config.EnableMessengerSubscriptions);
return;
}
messenger.RegisterWithAppServer(this);
}
@@ -1382,30 +1335,11 @@ namespace PepperDash.Essentials
{
Log =
{
Output = (data, message) =>
{
switch (data.Level)
{
case LogLevel.Trace:
this.LogVerbose(data.Message);
break;
case LogLevel.Debug:
this.LogDebug(data.Message);
break;
case LogLevel.Info:
this.LogInformation(data.Message);
break;
case LogLevel.Warn:
this.LogWarning(data.Message);
break;
case LogLevel.Error:
this.LogError(data.Message);
break;
case LogLevel.Fatal:
this.LogFatal(data.Message);
break;
}
}
Output = (data, s) =>
this.LogDebug(
"Message from websocket: {message}",
data
)
}
};
@@ -1449,13 +1383,13 @@ namespace PepperDash.Essentials
private void SetWebsocketDebugLevel(string cmdparameters)
{
// if (CrestronEnvironment.ProgramCompatibility == eCrestronSeries.Series4)
// {
// this.LogInformation(
// "Setting websocket log level not currently allowed on 4 series."
// );
// return; // Web socket log level not currently allowed in series4
// }
if (CrestronEnvironment.ProgramCompatibility == eCrestronSeries.Series4)
{
this.LogInformation(
"Setting websocket log level not currently allowed on 4 series."
);
return; // Web socket log level not currently allowed in series4
}
if (string.IsNullOrEmpty(cmdparameters))
{
@@ -1481,8 +1415,6 @@ namespace PepperDash.Essentials
_wsClient2.Log.Level = _wsLogLevel;
}
_directServer?.SetWebsocketLogLevel(_wsLogLevel);
CrestronConsole.ConsoleCommandResponse($"Websocket log level set to {debugLevel}");
}
catch
@@ -1552,7 +1484,7 @@ namespace PepperDash.Essentials
/// <summary>
/// Adds an action to the dictionary
/// </summary>
/// <param name="messenger">The messenger for the API command</param>
/// <param name="key">The path of the API command</param>
/// <param name="action">The action to be triggered by the commmand</param>
public void AddAction<T>(T messenger, Action<string, string, JToken> action)
where T : IMobileControlMessenger
@@ -2262,21 +2194,8 @@ namespace PepperDash.Essentials
return;
}
if (_roomCombiner.CurrentScenario == null)
{
var message = new MobileControlMessage
{
Type = "/system/roomKey",
ClientId = clientId,
Content = roomKey
};
SendMessageObject(message);
return;
}
if (!_roomCombiner.CurrentScenario.UiMap.ContainsKey(roomKey))
{
this.LogWarning(
"Unable to find correct roomKey for {roomKey} in current scenario. Returning {roomKey} as roomKey", roomKey);
@@ -2501,4 +2420,33 @@ namespace PepperDash.Essentials
CrestronConsole.ConsoleCommandResponse("Usage: mobilehttprequest:N get/post url\r");
}
}
/// <summary>
/// Represents a ClientSpecificUpdateRequest
/// </summary>
public class ClientSpecificUpdateRequest
{
public ClientSpecificUpdateRequest(Action<string> action)
{
ResponseMethod = action;
}
/// <summary>
/// Gets or sets the ResponseMethod
/// </summary>
public Action<string> ResponseMethod { get; private set; }
}
/// <summary>
/// Represents a UserCodeChanged
/// </summary>
public class UserCodeChanged
{
public Action<string, string> UpdateUserCode { get; private set; }
public UserCodeChanged(Action<string, string> updateMethod)
{
UpdateUserCode = updateMethod;
}
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
@@ -20,6 +17,9 @@ using PepperDash.Essentials.Devices.Common.Room;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.WebSocketServer;
using System;
using System.Collections.Generic;
using System.Linq;
using IShades = PepperDash.Essentials.Core.Shades.IShades;
using ShadeBase = PepperDash.Essentials.Devices.Common.Shades.ShadeBase;
@@ -485,7 +485,6 @@ namespace PepperDash.Essentials.RoomBridges
/// Sends the full status of the room to the server
/// </summary>
/// <param name="room"></param>
/// <param name="id"></param>
private void SendFullStatusForClientId(string id, IEssentialsRoom room)
{
//Parent.SendMessageObject(GetFullStatus(room));
@@ -555,7 +554,6 @@ namespace PepperDash.Essentials.RoomBridges
/// <summary>
/// Determines the configuration of the room and the details about the devices associated with the room
/// </summary>
/// <param name="room"></param>
/// <returns></returns>
private RoomConfiguration GetRoomConfiguration(IEssentialsRoom room)
@@ -800,38 +798,31 @@ namespace PepperDash.Essentials.RoomBridges
/// </summary>
public class RoomStateMessage : DeviceStateMessageBase
{
[JsonProperty("configuration", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Configuration
/// </summary>
[JsonProperty("configuration", NullValueHandling = NullValueHandling.Ignore)]
public RoomConfiguration Configuration { get; set; }
[JsonProperty("activityMode", NullValueHandling = NullValueHandling.Ignore)]
public int? ActivityMode { get; set; }
[JsonProperty("advancedSharingActive", NullValueHandling = NullValueHandling.Ignore)]
public bool? AdvancedSharingActive { get; set; }
[JsonProperty("isOn", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsOn { get; set; }
[JsonProperty("isWarmingUp", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsWarmingUp { get; set; }
[JsonProperty("isCoolingDown", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsCoolingDown { get; set; }
[JsonProperty("selectedSourceKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the SelectedSourceKey
/// </summary>
[JsonProperty("selectedSourceKey", NullValueHandling = NullValueHandling.Ignore)]
public string SelectedSourceKey { get; set; }
[JsonProperty("share", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Share
/// </summary>
[JsonProperty("share", NullValueHandling = NullValueHandling.Ignore)]
public ShareState Share { get; set; }
[JsonProperty("volumes", NullValueHandling = NullValueHandling.Ignore)]
@@ -846,16 +837,13 @@ namespace PepperDash.Essentials.RoomBridges
/// </summary>
public class ShareState
{
[JsonProperty("currentShareText", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the CurrentShareText
/// </summary>
[JsonProperty("currentShareText", NullValueHandling = NullValueHandling.Ignore)]
public string CurrentShareText { get; set; }
[JsonProperty("enabled", NullValueHandling = NullValueHandling.Ignore)]
public bool? Enabled { get; set; }
[JsonProperty("isSharing", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsSharing { get; set; }
}
@@ -865,156 +853,131 @@ namespace PepperDash.Essentials.RoomBridges
/// </summary>
public class RoomConfiguration
{
//[JsonProperty("shutdownPromptSeconds", NullValueHandling = NullValueHandling.Ignore)]
//public int? ShutdownPromptSeconds { get; set; }
[JsonProperty("hasVideoConferencing", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasVideoConferencing { get; set; }
[JsonProperty("videoCodecIsZoomRoom", NullValueHandling = NullValueHandling.Ignore)]
public bool? VideoCodecIsZoomRoom { get; set; }
[JsonProperty("hasAudioConferencing", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasAudioConferencing { get; set; }
[JsonProperty("hasEnvironmentalControls", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasEnvironmentalControls { get; set; }
[JsonProperty("hasCameraControls", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasCameraControls { get; set; }
[JsonProperty("hasSetTopBoxControls", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasSetTopBoxControls { get; set; }
[JsonProperty("hasRoutingControls", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasRoutingControls { get; set; }
[JsonProperty("touchpanelKeys", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the TouchpanelKeys
/// </summary>
[JsonProperty("touchpanelKeys", NullValueHandling = NullValueHandling.Ignore)]
public List<string> TouchpanelKeys { get; set; }
[JsonProperty("zoomRoomControllerKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the ZoomRoomControllerKey
/// </summary>
[JsonProperty("zoomRoomControllerKey", NullValueHandling = NullValueHandling.Ignore)]
public string ZoomRoomControllerKey { get; set; }
[JsonProperty("ciscoNavigatorKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the CiscoNavigatorKey
/// </summary>
[JsonProperty("ciscoNavigatorKey", NullValueHandling = NullValueHandling.Ignore)]
public string CiscoNavigatorKey { get; set; }
[JsonProperty("videoCodecKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the VideoCodecKey
/// </summary>
[JsonProperty("videoCodecKey", NullValueHandling = NullValueHandling.Ignore)]
public string VideoCodecKey { get; set; }
[JsonProperty("audioCodecKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the AudioCodecKey
/// </summary>
[JsonProperty("audioCodecKey", NullValueHandling = NullValueHandling.Ignore)]
public string AudioCodecKey { get; set; }
[JsonProperty("matrixRoutingKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the MatrixRoutingKey
/// </summary>
[JsonProperty("matrixRoutingKey", NullValueHandling = NullValueHandling.Ignore)]
public string MatrixRoutingKey { get; set; }
[JsonProperty("endpointKeys", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the EndpointKeys
/// </summary>
[JsonProperty("endpointKeys", NullValueHandling = NullValueHandling.Ignore)]
public List<string> EndpointKeys { get; set; }
[JsonProperty("accessoryDeviceKeys", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the AccessoryDeviceKeys
/// </summary>
[JsonProperty("accessoryDeviceKeys", NullValueHandling = NullValueHandling.Ignore)]
public List<string> AccessoryDeviceKeys { get; set; }
[JsonProperty("defaultDisplayKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the DefaultDisplayKey
/// </summary>
[JsonProperty("defaultDisplayKey", NullValueHandling = NullValueHandling.Ignore)]
public string DefaultDisplayKey { get; set; }
[JsonProperty("destinations", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<eSourceListItemDestinationTypes, string> Destinations { get; set; }
[JsonProperty("environmentalDevices", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the EnvironmentalDevices
/// </summary>
[JsonProperty("environmentalDevices", NullValueHandling = NullValueHandling.Ignore)]
public List<EnvironmentalDeviceConfiguration> EnvironmentalDevices { get; set; }
[JsonProperty("sourceList", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, SourceListItem> SourceList { get; set; }
[JsonProperty("destinationList", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, DestinationListItem> DestinationList { get; set; }
[JsonProperty("audioControlPointList", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the AudioControlPointList
/// </summary>
[JsonProperty("audioControlPointList", NullValueHandling = NullValueHandling.Ignore)]
public AudioControlPointListItem AudioControlPointList { get; set; }
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, CameraListItem> CameraList { get; set; }
[JsonProperty("defaultPresentationSourceKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the DefaultPresentationSourceKey
/// </summary>
[JsonProperty("defaultPresentationSourceKey", NullValueHandling = NullValueHandling.Ignore)]
public string DefaultPresentationSourceKey { get; set; }
[JsonProperty("helpMessage", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the HelpMessage
/// </summary>
[JsonProperty("helpMessage", NullValueHandling = NullValueHandling.Ignore)]
public string HelpMessage { get; set; }
[JsonProperty("techPassword", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the TechPassword
/// </summary>
[JsonProperty("techPassword", NullValueHandling = NullValueHandling.Ignore)]
public string TechPassword { get; set; }
[JsonProperty("uiBehavior", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the UiBehavior
/// </summary>
[JsonProperty("uiBehavior", NullValueHandling = NullValueHandling.Ignore)]
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
[JsonProperty("supportsAdvancedSharing", NullValueHandling = NullValueHandling.Ignore)]
public bool? SupportsAdvancedSharing { get; set; }
[JsonProperty("userCanChangeShareMode", NullValueHandling = NullValueHandling.Ignore)]
public bool? UserCanChangeShareMode { get; set; }
[JsonProperty("roomCombinerKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the RoomCombinerKey
/// </summary>
[JsonProperty("roomCombinerKey", NullValueHandling = NullValueHandling.Ignore)]
public string RoomCombinerKey { get; set; }
public RoomConfiguration()
@@ -1031,19 +994,17 @@ namespace PepperDash.Essentials.RoomBridges
/// </summary>
public class EnvironmentalDeviceConfiguration
{
[JsonProperty("deviceKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the DeviceKey
/// </summary>
[JsonProperty("deviceKey", NullValueHandling = NullValueHandling.Ignore)]
public string DeviceKey { get; private set; }
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("deviceType", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the DeviceType
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("deviceType", NullValueHandling = NullValueHandling.Ignore)]
public eEnvironmentalDeviceTypes DeviceType { get; private set; }
public EnvironmentalDeviceConfiguration(string key, eEnvironmentalDeviceTypes type)
@@ -1070,18 +1031,57 @@ namespace PepperDash.Essentials.RoomBridges
/// </summary>
public class ApiTouchPanelToken
{
[JsonProperty("touchPanels", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the TouchPanels
/// </summary>
[JsonProperty("touchPanels", NullValueHandling = NullValueHandling.Ignore)]
public List<JoinToken> TouchPanels { get; set; } = new List<JoinToken>();
[JsonProperty("userAppUrl", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the UserAppUrl
/// </summary>
[JsonProperty("userAppUrl", NullValueHandling = NullValueHandling.Ignore)]
public string UserAppUrl { get; set; } = "";
}
#if SERIES3
/// <summary>
/// Represents a SourceSelectMessageContent
/// </summary>
public class SourceSelectMessageContent
{
/// <summary>
/// Gets or sets the SourceListItem
/// </summary>
public string SourceListItem { get; set; }
/// <summary>
/// Gets or sets the SourceListKey
/// </summary>
public string SourceListKey { get; set; }
}
/// <summary>
/// Represents a DirectRoute
/// </summary>
public class DirectRoute
{
/// <summary>
/// Gets or sets the SourceKey
/// </summary>
public string SourceKey { get; set; }
/// <summary>
/// Gets or sets the DestinationKey
/// </summary>
public string DestinationKey { get; set; }
}
/// <summary>
///
/// </summary>
/// <param name="b"></param>
/// <summary>
/// Delegate for PressAndHoldAction
/// </summary>
public delegate void PressAndHoldAction(bool b);
#endif
}

View File

@@ -17,7 +17,6 @@ using PepperDash.Essentials.Core.DeviceInfo;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Core.UI;
using Feedback = PepperDash.Essentials.Core.Feedback;
using IPAddress = System.Net.IPAddress;
namespace PepperDash.Essentials.Touchpanel
{
@@ -107,14 +106,11 @@ namespace PepperDash.Essentials.Touchpanel
/// </summary>
public DeviceInfo DeviceInfo => new DeviceInfo();
/// <summary>
/// Gets the list of connected IPs for this IpId
/// </summary>
public ReadOnlyCollection<ConnectedIpInformation> ConnectedIps => Panel.ConnectedIpList;
private readonly IPAddress csIpAddress;
private System.Net.IPAddress csIpAddress;
private readonly IPAddress csSubnetMask;
private System.Net.IPAddress csSubnetMask;
/// <summary>
@@ -194,27 +190,12 @@ namespace PepperDash.Essentials.Touchpanel
RegisterForExtenders();
try
{
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);
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 = IPAddress.Parse(csSubnetMask);
this.csIpAddress = IPAddress.Parse(csIpAddress);
}
catch (ArgumentException)
{
Debug.LogInformation("This processor does not have a CS LAN", this);
}
catch (InvalidOperationException)
{
Debug.LogInformation("This processor does not have a CS LAN", this);
}
catch (Exception ex)
{
Debug.LogError($"Unexpected exception when checking CS LAN: {ex}", this);
}
this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask);
this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress);
}
/// <summary>
@@ -245,7 +226,7 @@ namespace PepperDash.Essentials.Touchpanel
{
x70Panel.ExtenderApplicationControlReservedSigs.DeviceExtenderSigChange += (e, a) =>
{
this.LogVerbose("X70 App Control Device Extender args: {event}:{sig}:{type}:{boolValue}:{ushortValue}:{stringValue}", a.Event, a.Sig, a.Sig.Type, a.Sig.BoolValue, a.Sig.UShortValue, a.Sig.StringValue);
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, this, $"X70 App Control Device Extender args: {a.Event}:{a.Sig}:{a.Sig.Type}:{a.Sig.BoolValue}:{a.Sig.UShortValue}:{a.Sig.StringValue}");
UpdateZoomFeedbacks();
@@ -264,7 +245,7 @@ namespace PepperDash.Essentials.Touchpanel
x70Panel.ExtenderZoomRoomAppReservedSigs.DeviceExtenderSigChange += (e, a) =>
{
this.LogVerbose("X70 Zoom Room App Device Extender args: {event}:{sig}:{type}:{boolValue}:{ushortValue}:{stringValue}", a.Event, a.Sig, a.Sig.Type, a.Sig.BoolValue, a.Sig.UShortValue, a.Sig.StringValue);
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, this, $"X70 Zoom Room Ap Device Extender args: {a.Event}:{a.Sig}:{a.Sig.Type}:{a.Sig.BoolValue}:{a.Sig.UShortValue}:{a.Sig.StringValue}");
if (a.Sig.Number == x70Panel.ExtenderZoomRoomAppReservedSigs.ZoomRoomIncomingCallFeedback.Number)
{
@@ -282,7 +263,7 @@ namespace PepperDash.Essentials.Touchpanel
DeviceInfo.MacAddress = x70Panel.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
DeviceInfo.IpAddress = x70Panel.ExtenderEthernetReservedSigs.IpAddressFeedback.StringValue;
this.LogDebug("MAC: {macAddress} IP: {ipAddress}", DeviceInfo.MacAddress, DeviceInfo.IpAddress);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, this, $"MAC: {DeviceInfo.MacAddress} IP: {DeviceInfo.IpAddress}");
var handler = DeviceInfoChanged;
@@ -312,7 +293,7 @@ namespace PepperDash.Essentials.Touchpanel
{
x60withZoomApp.ExtenderApplicationControlReservedSigs.DeviceExtenderSigChange += (e, a) =>
{
this.LogVerbose("X60 App Control Device Extender args: {event}:{sig}:{type}:{boolValue}:{ushortValue}:{stringValue}", a.Event, a.Sig, a.Sig.Type, a.Sig.BoolValue, a.Sig.UShortValue, a.Sig.StringValue);
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, this, $"X60 App Control Device Extender args: {a.Event}:{a.Sig}:{a.Sig.Type}:{a.Sig.BoolValue}:{a.Sig.UShortValue}:{a.Sig.StringValue}");
if (a.Sig.Number == x60withZoomApp.ExtenderApplicationControlReservedSigs.HideOpenApplicationFeedback.Number)
{
@@ -321,7 +302,7 @@ namespace PepperDash.Essentials.Touchpanel
};
x60withZoomApp.ExtenderZoomRoomAppReservedSigs.DeviceExtenderSigChange += (e, a) =>
{
this.LogVerbose("X60 Zoom Room App Device Extender args: {event}:{sig}:{type}:{boolValue}:{ushortValue}:{stringValue}", a.Event, a.Sig, a.Sig.Type, a.Sig.BoolValue, a.Sig.UShortValue, a.Sig.StringValue);
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, this, $"X60 Zoom Room App Device Extender args: {a.Event}:{a.Sig}:{a.Sig.Type}:{a.Sig.BoolValue}:{a.Sig.UShortValue}:{a.Sig.StringValue}");
if (a.Sig.Number == x60withZoomApp.ExtenderZoomRoomAppReservedSigs.ZoomRoomIncomingCallFeedback.Number)
{
@@ -338,7 +319,7 @@ namespace PepperDash.Essentials.Touchpanel
DeviceInfo.MacAddress = x60withZoomApp.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
DeviceInfo.IpAddress = x60withZoomApp.ExtenderEthernetReservedSigs.IpAddressFeedback.StringValue;
this.LogDebug("MAC: {macAddress} IP: {ipAddress}", DeviceInfo.MacAddress, DeviceInfo.IpAddress);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, this, $"MAC: {DeviceInfo.MacAddress} IP: {DeviceInfo.IpAddress}");
var handler = DeviceInfoChanged;
@@ -400,7 +381,7 @@ namespace PepperDash.Essentials.Touchpanel
/// <param name="args">The signal event arguments containing the changed signal information.</param>
protected override void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
{
this.LogVerbose("System Device Extender args: {event}:{sig}", args.Event, args.Sig);
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, this, $"System Device Extender args: ${args.Event}:${args.Sig}");
}
/// <summary>
@@ -455,7 +436,7 @@ namespace PepperDash.Essentials.Touchpanel
var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, lanAdapterId);
if (csIpAddress == null || csSubnetMask == null || url == null)
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;
@@ -466,7 +447,7 @@ namespace PepperDash.Essentials.Touchpanel
var ip = ConnectedIps.Any(ipInfo =>
{
if (IPAddress.TryParse(ipInfo.DeviceIpAddress, out var parsedIp))
if (System.Net.IPAddress.TryParse(ipInfo.DeviceIpAddress, out var parsedIp))
{
return csIpAddress.IsInSameSubnet(parsedIp, csSubnetMask);
}
@@ -500,7 +481,7 @@ namespace PepperDash.Essentials.Touchpanel
if (mcList.Count == 0)
{
this.LogError("No Mobile Control controller found");
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, this, $"No Mobile Control controller found");
return;
}
@@ -512,7 +493,7 @@ namespace PepperDash.Essentials.Touchpanel
if (bridge == null)
{
this.LogInformation("No Mobile Control bridge for {roomKey} found", _config.DefaultRoomKey);
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, this, $"No Mobile Control bridge for {_config.DefaultRoomKey} found ");
return;
}
@@ -521,7 +502,7 @@ namespace PepperDash.Essentials.Touchpanel
_bridge.UserCodeChanged += UpdateFeedbacks;
_bridge.AppUrlChanged += (s, a) =>
{
this.LogInformation("AppURL changed: {appURL}", _bridge.AppUrl);
this.LogInformation("AppURL changed");
SetAppUrl(_bridge.AppUrl);
UpdateFeedbacks(s, a);
};
@@ -557,7 +538,7 @@ namespace PepperDash.Essentials.Touchpanel
{
foreach (var feedback in ZoomFeedbacks)
{
this.LogDebug("Updating {feedbackKey}", feedback.Key);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, this, $"Updating {feedback.Key}");
feedback.FireUpdate();
}
}
@@ -593,7 +574,7 @@ namespace PepperDash.Essentials.Touchpanel
if (Panel is TswX60WithZoomRoomAppReservedSigs)
{
this.LogInformation("X60 panel does not support zoom app");
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, this, $"X60 panel does not support zoom app");
return;
}
}
@@ -669,16 +650,7 @@ namespace PepperDash.Essentials.Touchpanel
handler(this, new DeviceInfoEventArgs(DeviceInfo));
}
this.LogDebug("MAC: {macAddress} IP: {ipAddress}", DeviceInfo.MacAddress, DeviceInfo.IpAddress);
}
/// <summary>
/// Force a reload of the iframe on the panel connected to this IP ID
/// </summary>
public void ReloadIframe()
{
this.LogInformation("Pulsing join 1");
Panel.PulseBool(1, 100);
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, this, $"MAC: {DeviceInfo.MacAddress} IP: {DeviceInfo.IpAddress}");
}
}
@@ -687,8 +659,6 @@ namespace PepperDash.Essentials.Touchpanel
/// </summary>
public class MobileControlTouchpanelControllerFactory : EssentialsPluginDeviceFactory<MobileControlTouchpanelController>
{
private Dictionary<string, Func<uint, CrestronControlSystem, string, BasicTriListWithSmartObject>> factories;
/// <summary>
/// Initializes a new instance of the MobileControlTouchpanelControllerFactory class.
/// Sets up supported device type names and minimum framework version requirements.
@@ -697,31 +667,6 @@ namespace PepperDash.Essentials.Touchpanel
{
TypeNames = new List<string>() { "mccrestronapp", "mctsw550", "mctsw750", "mctsw1050", "mctsw560", "mctsw760", "mctsw1060", "mctsw570", "mctsw770", "mcts770", "mctsw1070", "mcts1070", "mcxpanel", "mcdge1000" };
MinimumEssentialsFrameworkVersion = "2.0.0";
factories = new Dictionary<string, Func<uint, CrestronControlSystem, string, BasicTriListWithSmartObject>>
{
{"crestronapp", (id, controlSystem, projectName) => {
var app = new CrestronApp(id, Global.ControlSystem);
app.ParameterProjectName.Value = projectName;
return app;
}},
{"xpanel", (id, controlSystem, projectName) => new XpanelForHtml5(id, controlSystem)},
{"tsw550", (id, controlSystem, projectName) => new Tsw550(id, controlSystem)},
{"tsw552", (id, controlSystem, projectName) => new Tsw552(id, controlSystem)},
{"tsw560", (id, controlSystem, projectName) => new Tsw560(id, controlSystem)},
{"tsw750", (id, controlSystem, projectName) => new Tsw750(id, controlSystem)},
{"tsw752", (id, controlSystem, projectName) => new Tsw752(id, controlSystem)},
{"tsw760", (id, controlSystem, projectName) => new Tsw760(id, controlSystem)},
{"tsw1050", (id, controlSystem, projectName) => new Tsw1050(id, controlSystem)},
{"tsw1052", (id, controlSystem, projectName) => new Tsw1052(id, controlSystem)},
{"tsw1060", (id, controlSystem, projectName) => new Tsw1060(id, controlSystem)},
{"tsw570", (id, controlSystem, projectName) => new Tsw570(id, controlSystem)},
{"tsw770", (id, controlSystem, projectName) => new Tsw770(id, controlSystem)},
{"ts770", (id, controlSystem, projectName) => new Ts770(id, controlSystem)},
{"tsw1070", (id, controlSystem, projectName) => new Tsw1070(id, controlSystem)},
{"ts1070", (id, controlSystem, projectName) => new Ts1070(id, controlSystem)},
{"dge1000", (id, controlSystem, projectName) => new Dge1000(id, controlSystem)}
};
}
/// <summary>
@@ -741,10 +686,10 @@ namespace PepperDash.Essentials.Touchpanel
if (panel == null)
{
Debug.LogError("Unable to create Touchpanel for type {type}. Touchpanel Controller WILL NOT function correctly", dc.Type);
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Unable to create Touchpanel for type {0}. Touchpanel Controller WILL NOT function correctly", dc.Type);
}
Debug.LogDebug("Factory Attempting to create new MobileControlTouchpanelController");
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Factory Attempting to create new MobileControlTouchpanelController");
var panelController = new MobileControlTouchpanelController(dc.Key, dc.Name, panel, props);
@@ -754,21 +699,56 @@ namespace PepperDash.Essentials.Touchpanel
private BasicTriListWithSmartObject GetPanelForType(string type, uint id, string projectName)
{
type = type.ToLower().Replace("mc", "");
try
{
if (!factories.TryGetValue(type, out var buildCrestronHardwareDevice))
if (type == "crestronapp")
{
Debug.LogError("Cannot create TSW controller with type {type}", type);
var app = new CrestronApp(id, Global.ControlSystem);
app.ParameterProjectName.Value = projectName;
return app;
}
else if (type == "xpanel")
return new XpanelForHtml5(id, Global.ControlSystem);
else if (type == "tsw550")
return new Tsw550(id, Global.ControlSystem);
else if (type == "tsw552")
return new Tsw552(id, Global.ControlSystem);
else if (type == "tsw560")
return new Tsw560(id, Global.ControlSystem);
else if (type == "tsw750")
return new Tsw750(id, Global.ControlSystem);
else if (type == "tsw752")
return new Tsw752(id, Global.ControlSystem);
else if (type == "tsw760")
return new Tsw760(id, Global.ControlSystem);
else if (type == "tsw1050")
return new Tsw1050(id, Global.ControlSystem);
else if (type == "tsw1052")
return new Tsw1052(id, Global.ControlSystem);
else if (type == "tsw1060")
return new Tsw1060(id, Global.ControlSystem);
else if (type == "tsw570")
return new Tsw570(id, Global.ControlSystem);
else if (type == "tsw770")
return new Tsw770(id, Global.ControlSystem);
else if (type == "ts770")
return new Ts770(id, Global.ControlSystem);
else if (type == "tsw1070")
return new Tsw1070(id, Global.ControlSystem);
else if (type == "ts1070")
return new Ts1070(id, Global.ControlSystem);
else if (type == "dge1000")
return new Dge1000(id, Global.ControlSystem);
else
{
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "WARNING: Cannot create TSW controller with type '{0}'", type);
return null;
}
return buildCrestronHardwareDevice(id, Global.ControlSystem, projectName);
}
catch (Exception e)
{
Debug.LogError("Cannot create TSW base class. Panel will not function: {message}", e.Message);
Debug.LogDebug(e, "Stack Trace: ");
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
return null;
}
}

View File

@@ -8,32 +8,28 @@ namespace PepperDash.Essentials.Touchpanel
/// </summary>
public class MobileControlTouchpanelProperties : CrestronTouchpanelPropertiesConfig
{
[JsonProperty("useDirectServer")]
/// <summary>
/// Gets or sets the UseDirectServer
/// </summary>
[JsonProperty("useDirectServer")]
public bool UseDirectServer { get; set; } = false;
[JsonProperty("zoomRoomController")]
/// <summary>
/// Gets or sets the ZoomRoomController
/// </summary>
[JsonProperty("zoomRoomController")]
public bool ZoomRoomController { get; set; } = false;
[JsonProperty("buttonToolbarTimeoutInS")]
/// <summary>
/// Gets or sets the ButtonToolbarTimoutInS
/// </summary>
[JsonProperty("buttonToolbarTimeoutInS")]
public ushort ButtonToolbarTimoutInS { get; set; } = 0;
[JsonProperty("theme")]
/// <summary>
/// Gets or sets the Theme
/// </summary>
[JsonProperty("theme")]
public string Theme { get; set; } = "light";
}
}

View File

@@ -42,11 +42,10 @@ namespace PepperDash.Essentials.Touchpanel
/// </summary>
public class ThemeUpdateMessage : DeviceStateMessageBase
{
[JsonProperty("theme")]
/// <summary>
/// Gets or sets the Theme
/// </summary>
[JsonProperty("theme")]
public string Theme { get; set; }
}
}

View File

@@ -1,17 +0,0 @@
using System;
namespace PepperDash.Essentials
{
/// <summary>
/// Represents a UserCodeChanged
/// </summary>
public class UserCodeChanged
{
public Action<string, string> UpdateUserCode { get; private set; }
public UserCodeChanged(Action<string, string> updateMethod)
{
UpdateUserCode = updateMethod;
}
}
}

View File

@@ -7,18 +7,16 @@ namespace PepperDash.Essentials
/// </summary>
public class UserCodeChangedContent
{
[JsonProperty("userCode")]
/// <summary>
/// Gets or sets the UserCode
/// </summary>
[JsonProperty("userCode")]
public string UserCode { get; set; }
[JsonProperty("qrChecksum", NullValueHandling = NullValueHandling.Include)]
/// <summary>
/// Gets or sets the QrChecksum
/// </summary>
[JsonProperty("qrChecksum", NullValueHandling = NullValueHandling.Include)]
public string QrChecksum { get; set; }
}
}

View File

@@ -1,5 +1,5 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace PepperDash.Essentials
{
@@ -8,11 +8,10 @@ namespace PepperDash.Essentials
/// </summary>
public class Volumes
{
[JsonProperty("master", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Master
/// </summary>
[JsonProperty("master", NullValueHandling = NullValueHandling.Ignore)]
public Volume Master { get; set; }
[JsonProperty("auxFaders", NullValueHandling = NullValueHandling.Ignore)]
@@ -31,11 +30,10 @@ namespace PepperDash.Essentials
/// </summary>
public class Volume
{
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Key
/// </summary>
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
public string Key { get; set; }
[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
@@ -44,11 +42,10 @@ namespace PepperDash.Essentials
[JsonProperty("muted", NullValueHandling = NullValueHandling.Ignore)]
public bool? Muted { get; set; }
[JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Label
/// </summary>
[JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
public string Label { get; set; }
[JsonProperty("hasMute", NullValueHandling = NullValueHandling.Ignore)]
@@ -61,11 +58,10 @@ namespace PepperDash.Essentials
public bool? PrivacyMuted { get; set; }
[JsonProperty("muteIcon", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the MuteIcon
/// </summary>
[JsonProperty("muteIcon", NullValueHandling = NullValueHandling.Ignore)]
public string MuteIcon { get; set; }
public Volume(string key, int level, bool muted, string label, bool hasMute, string muteIcon)

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp.WebScripting;
using Crestron.SimplSharp.WebScripting;
using Newtonsoft.Json;
using PepperDash.Core.Web.RequestHandlers;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.WebApiHandlers
{
@@ -51,18 +51,16 @@ namespace PepperDash.Essentials.WebApiHandlers
/// </summary>
public class ActionPath
{
[JsonProperty("messengerKey")]
/// <summary>
/// Gets or sets the MessengerKey
/// </summary>
[JsonProperty("messengerKey")]
public string MessengerKey { get; set; }
[JsonProperty("path")]
/// <summary>
/// Gets or sets the Path
/// </summary>
[JsonProperty("path")]
public string Path { get; set; }
}
}

View File

@@ -148,25 +148,22 @@ namespace PepperDash.Essentials.WebApiHandlers
/// </summary>
public class ClientRequest
{
[JsonProperty("roomKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the RoomKey
/// </summary>
[JsonProperty("roomKey", NullValueHandling = NullValueHandling.Ignore)]
public string RoomKey { get; set; }
[JsonProperty("grantCode", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the GrantCode
/// </summary>
[JsonProperty("grantCode", NullValueHandling = NullValueHandling.Ignore)]
public string GrantCode { get; set; }
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Token
/// </summary>
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
public string Token { get; set; }
}
@@ -175,25 +172,22 @@ namespace PepperDash.Essentials.WebApiHandlers
/// </summary>
public class ClientResponse
{
[JsonProperty("error", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Error
/// </summary>
[JsonProperty("error", NullValueHandling = NullValueHandling.Ignore)]
public string Error { get; set; }
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Token
/// </summary>
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
public string Token { get; set; }
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Path
/// </summary>
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
public string Path { get; set; }
}
}

View File

@@ -1,28 +0,0 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using PepperDash.Core;
/// <summary>
/// Represents info about a device including supproted interfaces
/// </summary>
public class DeviceInterfaceInfo : IKeyName
{
/// <summary>
/// Gets or sets the Key
/// </summary>
[JsonProperty("key")]
public string Key { get; set; }
/// <summary>
/// Gets or sets the Name
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets the Interfaces
/// </summary>
[JsonProperty("interfaces")]
public List<string> Interfaces { get; set; }
}

View File

@@ -1,74 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace PepperDash.Essentials.WebSocketServer
{
/// <summary>
/// Represents a JoinResponse
/// </summary>
public class JoinResponse
{
/// <summary>
/// Gets or sets the ClientId
/// </summary>
[JsonProperty("clientId")]
public string ClientId { get; set; }
[JsonProperty("roomKey")]
public string RoomKey { get; set; }
[JsonProperty("systemUUid")]
public string SystemUuid { get; set; }
/// <summary>
/// Gets or sets the RoomUuid
/// </summary>
[JsonProperty("roomUUid")]
public string RoomUuid { get; set; }
/// <summary>
/// Gets or sets the Config
/// </summary>
[JsonProperty("config")]
public object Config { get; set; }
/// <summary>
/// Gets or sets the CodeExpires
/// </summary>
[JsonProperty("codeExpires")]
public DateTime CodeExpires { get; set; }
/// <summary>
/// Gets or sets the UserCode
/// </summary>
[JsonProperty("userCode")]
public string UserCode { get; set; }
/// <summary>
/// Gets or sets the UserAppUrl
/// </summary>
[JsonProperty("userAppUrl")]
public string UserAppUrl { get; set; }
/// <summary>
/// Gets or sets the EnableDebug
/// </summary>
[JsonProperty("enableDebug")]
public bool EnableDebug { get; set; }
/// <summary>
/// Gets or sets the DeviceInterfaceSupport
/// </summary>
[JsonProperty("deviceInterfaceSupport")]
public Dictionary<string, DeviceInterfaceInfo> DeviceInterfaceSupport { get; set; }
}
}

View File

@@ -1,24 +0,0 @@
namespace PepperDash.Essentials.WebSocketServer
{
/// <summary>
/// Represents a JoinToken
/// </summary>
public class JoinToken
{
/// <summary>
/// Gets or sets the Code
/// </summary>
public string Code { get; set; }
public string RoomKey { get; set; }
public string Uuid { get; set; }
public string TouchpanelKey { get; set; } = "";
/// <summary>
/// Gets or sets the Token
/// </summary>
public string Token { get; set; } = null;
}
}

View File

@@ -4,8 +4,6 @@ using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.WebScripting;
@@ -37,10 +35,6 @@ namespace PepperDash.Essentials.WebSocketServer
private readonly string appConfigFileName = "_config.local.json";
private readonly string appConfigCsFileName = "_config.cs.json";
private const string certificateName = "selfCres";
private const string certificatePassword = "cres12345";
/// <summary>
/// Where the key is the join token and the value is the room key
/// </summary>
@@ -161,7 +155,7 @@ namespace PepperDash.Essentials.WebSocketServer
{
try
{
this.LogInformation("Automatically forwarding port {port} to CS LAN", Port);
Debug.LogMessage(LogEventLevel.Information, "Automatically forwarding port {0} to CS LAN", Port);
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
var csIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
@@ -170,17 +164,16 @@ namespace PepperDash.Essentials.WebSocketServer
if (result != CrestronEthernetHelper.PortForwardingUserPatRetCodes.NoErr)
{
this.LogError("Error adding port forwarding: {error}", result);
Debug.LogMessage(LogEventLevel.Error, "Error adding port forwarding: {0}", result);
}
}
catch (ArgumentException)
{
this.LogInformation("This processor does not have a CS LAN", this);
Debug.LogMessage(LogEventLevel.Information, "This processor does not have a CS LAN", this);
}
catch (Exception ex)
{
this.LogError("Error automatically forwarding port to CS LAN: {message}", ex.Message);
this.LogDebug(ex, "Stack Trace");
Debug.LogMessage(ex, "Error automatically forwarding port to CS LAN");
}
}
@@ -197,7 +190,7 @@ namespace PepperDash.Essentials.WebSocketServer
{
if (parent.Config.DirectServer.AutomaticallyForwardPortToCSLAN == false)
{
this.LogInformation("This processor does not have a CS LAN");
Debug.LogMessage(LogEventLevel.Information, "This processor does not have a CS LAN", this);
}
}
@@ -266,49 +259,13 @@ namespace PepperDash.Essentials.WebSocketServer
_server.OnPost += Server_OnPost;
}
if (_parent.Config.DirectServer.Secure)
{
this.LogInformation("Adding SSL Configuration to server");
_server.SslConfiguration = new ServerSslConfiguration(new X509Certificate2($"\\user\\{certificateName}.pfx", certificatePassword))
{
ClientCertificateRequired = false,
CheckCertificateRevocation = false,
EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11
};
}
_server.Log.Output = (data, message) =>
{
switch (data.Level)
{
case LogLevel.Trace:
this.LogVerbose(data.Message);
break;
case LogLevel.Debug:
this.LogDebug(data.Message);
break;
case LogLevel.Info:
this.LogInformation(data.Message);
break;
case LogLevel.Warn:
this.LogWarning(data.Message);
break;
case LogLevel.Error:
this.LogError(data.Message);
break;
case LogLevel.Fatal:
this.LogFatal(data.Message);
break;
}
};
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
_server.Start();
if (_server.IsListening)
{
this.LogInformation("Mobile Control WebSocket Server listening on port {port}", _server.Port);
Debug.LogMessage(LogEventLevel.Information, "Mobile Control WebSocket Server listening on port {port}", this, _server.Port);
}
CrestronEnvironment.ProgramStatusEventHandler += OnProgramStop;
@@ -321,17 +278,10 @@ namespace PepperDash.Essentials.WebSocketServer
}
catch (Exception ex)
{
this.LogError("Exception initializing direct server: {message}", ex.Message);
this.LogDebug(ex, "Stack Trace");
Debug.LogMessage(ex, "Exception intializing websocket server", this);
}
}
public void SetWebsocketLogLevel(LogLevel level)
{
CrestronConsole.ConsoleCommandResponse($"Setting direct server debug level to {level}", level.ToString());
_server.Log.Level = level;
}
private void AddClientsForTouchpanels()
{
var touchpanels = DeviceManager.AllDevices
@@ -397,6 +347,22 @@ namespace PepperDash.Essentials.WebSocketServer
string ip = processorIp;
// 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 = csIpAddress.ToString();
@@ -511,8 +477,7 @@ namespace PepperDash.Essentials.WebSocketServer
}
catch (Exception ex)
{
this.LogError("Error getting application configuration: {message}", ex.Message);
this.LogDebug(ex, "Stack Trace");
this.LogError(ex, "Error getting application configuration");
return null;
}
@@ -548,14 +513,15 @@ namespace PepperDash.Essentials.WebSocketServer
{
if (token.Value == null)
{
this.LogWarning("Token value is null");
Debug.LogMessage(LogEventLevel.Warning, "Token value is null", this);
continue;
}
this.LogInformation("Adding token: {key} for room: {roomKey}", token.Key, token.Value.RoomKey);
Debug.LogMessage(LogEventLevel.Information, "Adding token: {0} for room: {1}", this, token.Key, token.Value.RoomKey);
if (UiClients == null)
{
Debug.LogMessage(LogEventLevel.Warning, "UiClients is null", this);
UiClients = new Dictionary<string, UiClientContext>();
}
@@ -565,7 +531,7 @@ namespace PepperDash.Essentials.WebSocketServer
if (UiClients.Count > 0)
{
this.LogInformation("Restored {uiClientCount} UiClients from secrets data", UiClients.Count);
Debug.LogMessage(LogEventLevel.Information, "Restored {uiClientCount} UiClients from secrets data", this, UiClients.Count);
foreach (var client in UiClients)
{
@@ -575,28 +541,36 @@ namespace PepperDash.Essentials.WebSocketServer
_server.AddWebSocketService(path, () =>
{
var c = new UiClient($"uiclient-{key}-{roomKey}");
this.LogDebug("Constructing UiClient with id: {key}", key);
var c = new UiClient();
Debug.LogMessage(LogEventLevel.Debug, "Constructing UiClient with id: {key}", this, key);
c.Controller = _parent;
c.RoomKey = roomKey;
UiClients[key].SetClient(c);
return c;
});
//_server.WebSocketServices.AddService<UiClient>(path, (c) =>
//{
// Debug.Console(2, this, "Constructing UiClient with id: {0}", key);
// c.Controller = _parent;
// c.RoomKey = roomKey;
// UiClients[key].SetClient(c);
//});
}
}
}
else
{
this.LogWarning("No secret found");
Debug.LogMessage(LogEventLevel.Warning, "No secret found");
}
this.LogDebug("{uiClientCount} UiClients restored from secrets data", UiClients.Count);
Debug.LogMessage(LogEventLevel.Debug, "{uiClientCount} UiClients restored from secrets data", this, UiClients.Count);
}
catch (Exception ex)
{
this.LogError("Exception retrieving secret: {message}", ex.Message);
this.LogDebug(ex, "Stack Trace");
Debug.LogMessage(ex, "Exception retrieving secret", this);
}
}
@@ -609,7 +583,7 @@ namespace PepperDash.Essentials.WebSocketServer
{
if (_secret == null)
{
this.LogError("Secret is null");
Debug.LogMessage(LogEventLevel.Error, "Secret is null", this);
_secret = new ServerTokenSecrets(string.Empty);
}
@@ -627,8 +601,7 @@ namespace PepperDash.Essentials.WebSocketServer
}
catch (Exception ex)
{
this.LogError("Exception updating secret: {message}", ex.Message);
this.LogDebug(ex, "Stack Trace");
Debug.LogMessage(ex, "Exception updating secret", this);
}
}
@@ -731,18 +704,18 @@ namespace PepperDash.Essentials.WebSocketServer
_server.AddWebSocketService(path, () =>
{
var c = new UiClient($"uiclient-{key}-{bridge.RoomKey}");
this.LogVerbose("Constructing UiClient with id: {key}", key);
var c = new UiClient();
Debug.LogMessage(LogEventLevel.Verbose, "Constructing UiClient with id: {0}", this, key);
c.Controller = _parent;
c.RoomKey = bridge.RoomKey;
UiClients[key].SetClient(c);
return c;
});
this.LogInformation("Added new WebSocket UiClient service at path: {path}", path);
this.LogInformation("Token: {@token}", token);
Debug.LogMessage(LogEventLevel.Information, "Added new WebSocket UiClient service at path: {path}", this, path);
Debug.LogMessage(LogEventLevel.Information, "Token: {@token}", this, token);
this.LogVerbose("{serviceCount} websocket services present", _server.WebSocketServices.Count);
Debug.LogMessage(LogEventLevel.Verbose, "{serviceCount} websocket services present", this, _server.WebSocketServices.Count);
UpdateSecret();
@@ -756,7 +729,7 @@ namespace PepperDash.Essentials.WebSocketServer
{
if (s == "?" || string.IsNullOrEmpty(s))
{
CrestronConsole.ConsoleCommandResponse(@"Remove all clients from the server. To execute add 'confirm' to command");
CrestronConsole.ConsoleCommandResponse(@"Removes all clients from the server. To execute add 'confirm' to command");
return;
}
@@ -910,8 +883,7 @@ namespace PepperDash.Essentials.WebSocketServer
}
catch (Exception ex)
{
this.LogError("Exception in OnGet handler: {message}", ex.Message);
this.LogDebug(ex, "Stack Trace");
Debug.LogMessage(ex, "Caught an exception in the OnGet handler", this);
}
}
@@ -1000,20 +972,6 @@ namespace PepperDash.Essentials.WebSocketServer
res.StatusCode = 200;
res.ContentType = "application/json";
var devices = DeviceManager.GetDevices();
Dictionary<string, DeviceInterfaceInfo> deviceInterfaces = new Dictionary<string, DeviceInterfaceInfo>();
foreach (var device in devices)
{
var interfaces = device?.GetType().GetInterfaces().Select((i) => i.Name).ToList() ?? new List<string>();
deviceInterfaces.Add(device.Key, new DeviceInterfaceInfo
{
Key = device.Key,
Name = device is IKeyName ? (device as IKeyName).Name : "",
Interfaces = interfaces
});
}
// Construct the response object
JoinResponse jRes = new JoinResponse
{
@@ -1027,8 +985,7 @@ namespace PepperDash.Essentials.WebSocketServer
UserAppUrl = string.Format("http://{0}:{1}/mc/app",
CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0),
Port),
EnableDebug = false,
DeviceInterfaceSupport = deviceInterfaces
EnableDebug = false
};
// Serialize to JSON and convert to Byte[]
@@ -1214,7 +1171,7 @@ namespace PepperDash.Essentials.WebSocketServer
}
else
{
this.LogWarning("File not found: {filePath}", filePath);
this.LogVerbose("File not found: {filePath}", filePath);
res.StatusCode = (int)HttpStatusCode.NotFound;
res.Close();
return;
@@ -1284,4 +1241,145 @@ namespace PepperDash.Essentials.WebSocketServer
}
}
}
/// <summary>
/// Represents a Version
/// </summary>
public class Version
{
[JsonProperty("serverVersion")]
public string ServerVersion { get; set; }
[JsonProperty("serverIsRunningOnProcessorHardware")]
public bool ServerIsRunningOnProcessorHardware { get; private set; }
public Version()
{
ServerIsRunningOnProcessorHardware = true;
}
}
/// <summary>
/// Represents a UiClientContext
/// </summary>
public class UiClientContext
{
/// <summary>
/// Gets or sets the Client
/// </summary>
public UiClient Client { get; private set; }
/// <summary>
/// Gets or sets the Token
/// </summary>
public JoinToken Token { get; private set; }
public UiClientContext(JoinToken token)
{
Token = token;
}
/// <summary>
/// SetClient method
/// </summary>
public void SetClient(UiClient client)
{
Client = client;
}
}
/// <summary>
/// Represents a ServerTokenSecrets
/// </summary>
public class ServerTokenSecrets
{
/// <summary>
/// Gets or sets the GrantCode
/// </summary>
public string GrantCode { get; set; }
public Dictionary<string, JoinToken> Tokens { get; set; }
public ServerTokenSecrets(string grantCode)
{
GrantCode = grantCode;
Tokens = new Dictionary<string, JoinToken>();
}
}
/// <summary>
/// Represents a JoinToken
/// </summary>
public class JoinToken
{
/// <summary>
/// Gets or sets the Code
/// </summary>
public string Code { get; set; }
public string RoomKey { get; set; }
public string Uuid { get; set; }
public string TouchpanelKey { get; set; } = "";
/// <summary>
/// Gets or sets the Token
/// </summary>
public string Token { get; set; } = null;
}
/// <summary>
/// Represents a JoinResponse
/// </summary>
public class JoinResponse
{
[JsonProperty("clientId")]
/// <summary>
/// Gets or sets the ClientId
/// </summary>
public string ClientId { get; set; }
[JsonProperty("roomKey")]
public string RoomKey { get; set; }
[JsonProperty("systemUUid")]
public string SystemUuid { get; set; }
[JsonProperty("roomUUid")]
/// <summary>
/// Gets or sets the RoomUuid
/// </summary>
public string RoomUuid { get; set; }
[JsonProperty("config")]
/// <summary>
/// Gets or sets the Config
/// </summary>
public object Config { get; set; }
[JsonProperty("codeExpires")]
/// <summary>
/// Gets or sets the CodeExpires
/// </summary>
public DateTime CodeExpires { get; set; }
[JsonProperty("userCode")]
/// <summary>
/// Gets or sets the UserCode
/// </summary>
public string UserCode { get; set; }
[JsonProperty("userAppUrl")]
/// <summary>
/// Gets or sets the UserAppUrl
/// </summary>
public string UserAppUrl { get; set; }
[JsonProperty("enableDebug")]
/// <summary>
/// Gets or sets the EnableDebug
/// </summary>
public bool EnableDebug { get; set; }
}
}

View File

@@ -1,24 +0,0 @@
using System.Collections.Generic;
namespace PepperDash.Essentials.WebSocketServer
{
/// <summary>
/// Represents a ServerTokenSecrets
/// </summary>
public class ServerTokenSecrets
{
/// <summary>
/// Gets or sets the GrantCode
/// </summary>
public string GrantCode { get; set; }
public Dictionary<string, JoinToken> Tokens { get; set; }
public ServerTokenSecrets(string grantCode)
{
GrantCode = grantCode;
Tokens = new Dictionary<string, JoinToken>();
}
}
}

Some files were not shown because too many files have changed in this diff Show More