Compare commits

..

4 Commits

Author SHA1 Message Date
Jonathan Arndt
ea983a6f37 Merge pull request #1333 from PepperDash:main
feat: merge main into custom branch
2025-09-22 13:47:03 -07:00
Jonathan Arndt
937a64f996 feat: updated Crestron db 2025-09-22 13:39:58 -07:00
Jonathan Arndt
54328536a8 feat: updated Crestron db 2025-09-22 13:33:04 -07:00
Jonathan Arndt
591f12f086 feature: update Crestron.SimplSharp.SDK.ProgramLibrary version to 2.21.157 across multiple projects 2025-09-17 15:53:08 -07:00
105 changed files with 1609 additions and 2743 deletions

View File

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

View File

@@ -43,7 +43,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" /> <PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
<PackageReference Include="Crestron.SimplSharp.SDK.Library" Version="2.21.90" /> <PackageReference Include="Crestron.SimplSharp.SDK.Library" Version="2.21.157" />
<PackageReference Include="Serilog" Version="3.1.1" /> <PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.Expressions" Version="4.0.0" /> <PackageReference Include="Serilog.Expressions" Version="4.0.0" />
<PackageReference Include="Serilog.Formatting.Compact" Version="2.0.0" /> <PackageReference Include="Serilog.Formatting.Compact" Version="2.0.0" />

View File

@@ -2,54 +2,59 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Core.CrestronIO namespace PepperDash.Essentials.Core.CrestronIO
{ {
[Description("Wrapper class for Digital Input")]
/// <summary> /// <summary>
/// Represents a GenericDigitalInputDevice /// Represents a GenericDigitalInputDevice
/// </summary> /// </summary>
/// [Description("Wrapper class for Digital Input")] public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IHasFeedback
{ {
private DigitalInput inputPort; /// <summary>
/// Gets or sets the InputPort
/// </summary>
public DigitalInput InputPort { get; private set; }
/// <summary> /// <summary>
/// Gets or sets the InputStateFeedback /// Gets or sets the InputStateFeedback
/// </summary> /// </summary>
public BoolFeedback InputStateFeedback { get; private set; } public BoolFeedback InputStateFeedback { get; private set; }
/// <inheritdoc /> Func<bool> InputStateFeedbackFunc
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>(); {
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, public GenericDigitalInputDevice(string key, string name, Func<IOPortConfig, DigitalInput> postActivationFunc,
IOPortConfig config) IOPortConfig config)
: base(key, name) : base(key, name)
{ {
InputStateFeedback = new BoolFeedback("inputState", () => inputPort.State); InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
AddPostActivationAction(() => 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) private static DigitalInput GetDigitalInput(IOPortConfig dc)
{ {
IDigitalInputPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor")) if (dc.PortDeviceKey.Equals("processor"))
{ {
if (!Global.ControlSystem.SupportsDigitalInput) 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 null;
} }
ioPortDevice = Global.ControlSystem;
return Global.ControlSystem.DigitalInputPorts[dc.PortNumber];
} }
else
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IDigitalInputPorts ioPortDevice))
{ {
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; return null;
} }
if (dc.PortNumber > ioPortDevice.NumberOfDigitalInputPorts) if (dc.PortNumber > ioPortDevice.NumberOfDigitalInputPorts)
{ {
Debug.LogError("GetDigitalInput: Device {key} does not contain a digital input port {port}", dc.PortDeviceKey, dc.PortNumber); Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
return null;
} }
return ioPortDevice.DigitalInputPorts[dc.PortNumber]; return ioPortDevice.DigitalInputPorts[dc.PortNumber];
} }
#endregion #endregion
@@ -116,20 +131,20 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
else 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 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 // Link feedback for input state
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]); InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
} }
catch (Exception e) catch (Exception e)
{ {
this.LogError("Unable to link device {key}. {message}", Key, e.Message); Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
this.LogDebug(e, "Stack Trace: "); Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
} }
} }
@@ -138,22 +153,22 @@ namespace PepperDash.Essentials.Core.CrestronIO
#region Factory #region Factory
/// <summary> /// <summary>
/// Factory for creating GenericDigitalInputDevice devices /// Represents a GenericDigitalInputDeviceFactory
/// </summary> /// </summary>
public class GenericDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericDigitalInputDevice> public class GenericDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericDigitalInputDevice>
{ {
/// <summary>
/// Constructor for GenericDigitalInputDeviceFactory
/// </summary>
public GenericDigitalInputDeviceFactory() public GenericDigitalInputDeviceFactory()
{ {
TypeNames = new List<string>() { "digitalinput" }; TypeNames = new List<string>() { "digitalinput" };
} }
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc /> /// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc) 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()); var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());

View File

@@ -2,64 +2,66 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json;
using Serilog.Events;
namespace PepperDash.Essentials.Core.CrestronIO namespace PepperDash.Essentials.Core.CrestronIO
{ {
/// <summary> /// <summary>
/// Represents a generic digital input deviced tied to a versiport /// Represents a generic digital input deviced tied to a versiport
/// </summary> /// </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; } 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; } public IntFeedback InputMinimumChangeFeedback { get; private set; }
/// <inheritdoc /> Func<int> InputValueFeedbackFunc
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>(); {
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) : public GenericVersiportAnalogInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name) base(key, name)
{ {
InputValueFeedback = new IntFeedback("inputValue", () => inputPort.AnalogIn); InputValueFeedback = new IntFeedback(InputValueFeedbackFunc);
InputMinimumChangeFeedback = new IntFeedback("inputMinimumChange", () => inputPort.AnalogMinChange); InputMinimumChangeFeedback = new IntFeedback(InputMinimumChangeFeedbackFunc);
AddPostActivationAction(() => AddPostActivationAction(() =>
{ {
inputPort = postActivationFunc(config); InputPort = postActivationFunc(config);
inputPort.Register(); InputPort.Register();
inputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput); InputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput);
inputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655); InputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655);
if (config.DisablePullUpResistor) 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> /// <summary>
/// Set minimum voltage change for device to update voltage changed method /// Set minimum voltage change for device to update voltage changed method
/// </summary> /// </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) public void SetMinimumChange(ushort value)
{ {
inputPort.AnalogMinChange = value; InputPort.AnalogMinChange = value;
} }
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args) 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(); InputValueFeedback.FireUpdate();
if (args.Event == eVersiportEvent.AnalogMinChangeChange) if (args.Event == eVersiportEvent.AnalogMinChangeChange)
InputMinimumChangeFeedback.FireUpdate(); InputMinimumChangeFeedback.FireUpdate();
@@ -86,6 +91,9 @@ namespace PepperDash.Essentials.Core.CrestronIO
#region Bridge Linking #region Bridge Linking
/// <summary>
/// LinkToApi method
/// </summary>
/// <inheritdoc /> /// <inheritdoc />
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{ {
@@ -102,12 +110,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
else 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 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 // Link feedback for input state
InputValueFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputValue.JoinNumber]); InputValueFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputValue.JoinNumber]);
@@ -117,8 +125,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
catch (Exception e) catch (Exception e)
{ {
this.LogError("Unable to link device {key}: {message}", Key, e.Message); Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
this.LogDebug(e, "Stack Trace: "); Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
} }
trilist.OnlineStatusChange += (d, args) => trilist.OnlineStatusChange += (d, args) =>
@@ -130,6 +138,11 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
void trilist_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
throw new NotImplementedException();
}
#endregion #endregion
@@ -138,55 +151,70 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary> /// </summary>
public static Versiport GetVersiportDigitalInput(IOPortConfig dc) public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
{ {
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor")) if (dc.PortDeviceKey.Equals("processor"))
{ {
if (!Global.ControlSystem.SupportsVersiport) 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 null;
} }
return Global.ControlSystem.VersiPorts[dc.PortNumber]; ioPortDevice = Global.ControlSystem;
} }
else
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
{ {
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; return null;
} }
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts) 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; 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 null;
} }
return ioPortDevice.VersiPorts[dc.PortNumber]; return ioPortDevice.VersiPorts[dc.PortNumber];
} }
} }
/// <summary> /// <summary>
/// Factory for creating GenericVersiportAnalogInputDevice devices /// Represents a GenericVersiportAbalogInputDeviceFactory
/// </summary> /// </summary>
public class GenericVersiportAnalogInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportAnalogInputDevice> public class GenericVersiportAbalogInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportAnalogInputDevice>
{ {
/// <summary> public GenericVersiportAbalogInputDeviceFactory()
/// Constructor for GenericVersiportAnalogInputDeviceFactory
/// </summary>
public GenericVersiportAnalogInputDeviceFactory()
{ {
TypeNames = new List<string>() { "versiportanaloginput" }; TypeNames = new List<string>() { "versiportanaloginput" };
} }
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc /> /// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc) 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()); var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());

View File

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

View File

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

View File

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

View File

@@ -14,28 +14,25 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary> /// </summary>
public class IOPortConfig public class IOPortConfig
{ {
[JsonProperty("portDeviceKey")]
/// <summary> /// <summary>
/// Gets or sets the PortDeviceKey /// Gets or sets the PortDeviceKey
/// </summary> /// </summary>
[JsonProperty("portDeviceKey")]
public string PortDeviceKey { get; set; } public string PortDeviceKey { get; set; }
[JsonProperty("portNumber")]
/// <summary> /// <summary>
/// Gets or sets the PortNumber /// Gets or sets the PortNumber
/// </summary> /// </summary>
[JsonProperty("portNumber")]
public uint PortNumber { get; set; } public uint PortNumber { get; set; }
[JsonProperty("disablePullUpResistor")]
/// <summary> /// <summary>
/// Gets or sets the DisablePullUpResistor /// Gets or sets the DisablePullUpResistor
/// </summary> /// </summary>
[JsonProperty("disablePullUpResistor")]
public bool DisablePullUpResistor { get; set; } public bool DisablePullUpResistor { get; set; }
[JsonProperty("minimumChange")]
/// <summary> /// <summary>
/// Gets or sets the MinimumChange /// Gets or sets the MinimumChange
/// </summary> /// </summary>
[JsonProperty("minimumChange")]
public int MinimumChange { get; set; } 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;
using System.Collections.ObjectModel;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces 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> /// <summary>
/// Defines the contract for IMobileControl /// Defines the contract for IMobileControl
/// </summary> /// </summary>
public interface IMobileControl : IKeyed public interface IMobileControl : IKeyed
{ {
/// <summary>
/// Gets the Host
/// </summary>
string Host { get; } string Host { get; }
/// <summary>
/// Gets the Client App URL
/// </summary>
string ClientAppUrl { get; } string ClientAppUrl { get; }
/// <summary>
/// Gets the System UUID
/// </summary>
string SystemUuid { get; } string SystemUuid { get; }
/// <summary>
/// Gets the ApiOnlineAndAuthorized feedback
/// </summary>
BoolFeedback ApiOnlineAndAuthorized { get; } BoolFeedback ApiOnlineAndAuthorized { get; }
/// <summary>
/// Sends the message object to the AppServer
/// </summary>
/// <param name="o">Message to send</param>
void SendMessageObject(IMobileControlMessage o); 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; 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); void RemoveAction(string key);
/// <summary>
/// Adds a device messenger
/// </summary>
/// <param name="messenger">Messenger to add</param>
void AddDeviceMessenger(IMobileControlMessenger messenger); void AddDeviceMessenger(IMobileControlMessenger messenger);
/// <summary>
/// Check if a device messenger exists
/// </summary>
/// <param name="key">Messenger key to find</param>
bool CheckForDeviceMessenger(string key); 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); 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; } public List<string> TypeNames { get; protected set; }
/// <summary> /// <summary>
/// Build the device using the configuration /// The method that will build the device
/// </summary> /// </summary>
/// <param name="dc">The device config</param> /// <param name="dc">The device config</param>
/// <returns>An instance of the device</returns> /// <returns>An instance of the device</returns>

View File

@@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Core
public interface IHasFeedback : IKeyed public interface IHasFeedback : IKeyed
{ {
/// <summary> /// <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. /// including all "aggregate" devices.
/// </summary> /// </summary>
FeedbackCollection<Feedback> Feedbacks { get; } FeedbackCollection<Feedback> Feedbacks { get; }

View File

@@ -25,7 +25,7 @@
<DocumentationFile>bin\$(Configuration)\PepperDash_Essentials_Core.xml</DocumentationFile> <DocumentationFile>bin\$(Configuration)\PepperDash_Essentials_Core.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" /> <PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.157" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Crestron\CrestronGenericBaseDevice.cs.orig" /> <None Include="Crestron\CrestronGenericBaseDevice.cs.orig" />

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

@@ -29,6 +29,6 @@
<ProjectReference Include="..\PepperDash.Essentials.Core\PepperDash.Essentials.Core.csproj" /> <ProjectReference Include="..\PepperDash.Essentials.Core\PepperDash.Essentials.Core.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" /> <PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.157" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

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

View File

@@ -1,8 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.Cameras;
@@ -11,12 +9,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary> /// <summary>
/// Messenger for a CameraBase device /// Messenger for a CameraBase device
/// </summary> /// </summary>
public class CameraBaseMessenger<T> : MessengerBase where T : IKeyed public class CameraBaseMessenger : MessengerBase
{ {
/// <summary> /// <summary>
/// Gets or sets the Camera /// Gets or sets the Camera
/// </summary> /// </summary>
public T Camera { get; set; } public CameraBase Camera { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
@@ -24,13 +22,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="camera"></param> /// <param name="camera"></param>
/// <param name="messagePath"></param> /// <param name="messagePath"></param>
public CameraBaseMessenger(string key, T camera, string messagePath) public CameraBaseMessenger(string key, CameraBase camera, string messagePath)
: base(key, messagePath, camera as IKeyName) : base(key, messagePath, camera)
{ {
if (camera == null) Camera = camera ?? throw new ArgumentNullException("camera");
throw new ArgumentNullException(nameof(camera));
Camera = camera;
if (Camera is IHasCameraPresets presetsCamera) if (Camera is IHasCameraPresets presetsCamera)
@@ -60,9 +55,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject(id)); AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject());
AddAction("/cameraStatus", (id, content) => SendCameraFullMessageObject(id));
if (Camera is IHasCameraPtzControl ptzCamera) if (Camera is IHasCameraPtzControl ptzCamera)
@@ -180,47 +173,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary> /// <summary>
/// Helper method to update the full status of the camera /// Helper method to update the full status of the camera
/// </summary> /// </summary>
private void SendCameraFullMessageObject(string id = null) private void SendCameraFullMessageObject()
{ {
var presetList = new List<CameraPreset>(); var presetList = new List<CameraPreset>();
CameraCapabilities capabilities = null;
if (Camera is IHasCameraPresets presetsCamera) if (Camera is IHasCameraPresets presetsCamera)
presetList = presetsCamera.Presets; presetList = presetsCamera.Presets;
if (Camera is ICameraCapabilities cameraCapabilities) PostStatusMessage(JToken.FromObject(new
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
{ {
CameraManualSupported = Camera is IHasCameraControls, cameraManualSupported = Camera is IHasCameraControls,
CameraAutoSupported = Camera is IHasCameraAutoMode, cameraAutoSupported = Camera is IHasCameraAutoMode,
CameraOffSupported = Camera is IHasCameraOff, cameraOffSupported = Camera is IHasCameraOff,
CameraMode = (eCameraControlMode)Enum.Parse(typeof(eCameraControlMode), GetCameraMode(), true), cameraMode = GetCameraMode(),
HasPresets = Camera is IHasCameraPresets, hasPresets = Camera is IHasCameraPresets,
Presets = presetList, presets = presetList
Capabilities = capabilities, })
IsFarEnd = Camera is IAmFarEndCamera
};
PostStatusMessage(message, id
); );
} }
@@ -240,59 +208,4 @@ namespace PepperDash.Essentials.AppServer.Messengers
return m; 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(); 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) => 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> /// <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 Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceInfo; using PepperDash.Essentials.Core.DeviceInfo;
using System.Timers;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -67,19 +67,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
debounceTimer.Start(); debounceTimer.Start();
}; };
AddAction("/fullStatus", (id, context) => SendFullStatus(id)); AddAction("/fullStatus", (id, context) => PostStatusMessage(new DeviceInfoStateMessage
AddAction("/deviceInfo", (id, content) => SendFullStatus(id));
AddAction("/update", (id, context) => _deviceInfoProvider.UpdateDeviceInfo());
}
private void SendFullStatus(string id = null)
{
PostStatusMessage(new DeviceInfoStateMessage
{ {
DeviceInfo = _deviceInfoProvider.DeviceInfo 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 Newtonsoft.Json;
using System.Collections.Generic;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging; using PepperDash.Core.Logging;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Core.Presets;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -16,24 +16,18 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
private readonly ITvPresetsProvider _presetsDevice; 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) public DevicePresetsModelMessenger(string key, string messagePath, ITvPresetsProvider presetsDevice)
: base(key, messagePath, presetsDevice as Device) : base(key, messagePath, presetsDevice as Device)
{ {
_presetsDevice = presetsDevice; _presetsDevice = presetsDevice;
} }
private void SendPresets(string id = null) private void SendPresets()
{ {
PostStatusMessage(new PresetStateMessage PostStatusMessage(new PresetStateMessage
{ {
Favorites = _presetsDevice.TvPresets.PresetsList Favorites = _presetsDevice.TvPresets.PresetsList
}, id); });
} }
private void RecallPreset(ISetTopBoxNumericKeypad device, string channel) private void RecallPreset(ISetTopBoxNumericKeypad device, string channel)
@@ -49,7 +43,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
#region Overrides of MessengerBase #region Overrides of MessengerBase
/// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
@@ -58,7 +51,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
this.LogInformation("getting full status for client {id}", id); this.LogInformation("getting full status for client {id}", id);
try try
{ {
SendPresets(id); SendPresets();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -66,8 +59,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
}); });
AddAction("/presetsStatus", (id, content) => SendPresets(id));
AddAction("/recall", (id, content) => AddAction("/recall", (id, content) =>
{ {
var p = content.ToObject<PresetChannelMessage>(); var p = content.ToObject<PresetChannelMessage>();
@@ -100,16 +91,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
public class PresetChannelMessage public class PresetChannelMessage
{ {
[JsonProperty("preset")]
/// <summary> /// <summary>
/// Gets or sets the Preset /// Gets or sets the Preset
/// </summary> /// </summary>
[JsonProperty("preset")]
public PresetChannel Preset; public PresetChannel Preset;
[JsonProperty("deviceKey")]
/// <summary> /// <summary>
/// Gets or sets the DeviceKey /// Gets or sets the DeviceKey
/// </summary> /// </summary>
[JsonProperty("deviceKey")]
public string DeviceKey; public string DeviceKey;
} }
@@ -118,11 +109,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
public class PresetStateMessage : DeviceStateMessageBase public class PresetStateMessage : DeviceStateMessageBase
{ {
[JsonProperty("favorites", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Favorites /// Gets or sets the Favorites
/// </summary> /// </summary>
[JsonProperty("favorites", NullValueHandling = NullValueHandling.Ignore)]
public List<PresetChannel> Favorites { get; set; } = new List<PresetChannel>(); 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.Converters;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using System;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -13,46 +12,35 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
public class DeviceVolumeMessenger : MessengerBase public class DeviceVolumeMessenger : MessengerBase
{ {
private readonly IBasicVolumeControls device; private readonly IBasicVolumeWithFeedback _localDevice;
/// <summary> public DeviceVolumeMessenger(string key, string messagePath, IBasicVolumeWithFeedback device)
/// 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)
: base(key, messagePath, device as IKeyName) : base(key, messagePath, device as IKeyName)
{ {
this.device = device; _localDevice = device;
} }
private void SendStatus(string id = null) private void SendStatus()
{ {
try try
{ {
if (!(device is IBasicVolumeWithFeedback feedbackDevice))
{
return;
}
var messageObj = new VolumeStateMessage var messageObj = new VolumeStateMessage
{ {
Volume = new Volume Volume = new Volume
{ {
Level = feedbackDevice?.VolumeLevelFeedback.IntValue ?? -1, Level = _localDevice?.VolumeLevelFeedback.IntValue ?? -1,
Muted = feedbackDevice?.MuteFeedback.BoolValue ?? false, Muted = _localDevice?.MuteFeedback.BoolValue ?? false,
HasMute = true, // assume all devices have mute for now 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.RawValue = volumeAdvanced.RawVolumeLevel.ToString();
messageObj.Volume.Units = volumeAdvanced.Units; messageObj.Volume.Units = volumeAdvanced.Units;
} }
PostStatusMessage(messageObj, id); PostStatusMessage(messageObj);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -62,26 +50,47 @@ namespace PepperDash.Essentials.AppServer.Messengers
#region Overrides of MessengerBase #region Overrides of MessengerBase
/// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
AddAction("/volumeUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => AddAction("/fullStatus", (id, content) => SendStatus());
{
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Calling {localDevice} volume up with {value}", DeviceKey, b); AddAction("/level", (id, content) =>
try {
{ var volume = content.ToObject<MobileControlSimpleContent<ushort>>();
device.VolumeUp(b);
} _localDevice.SetVolume(volume.Value);
catch (Exception ex) });
{
Debug.LogMessage(ex, "Got exception during volume up: {Exception}", null, ex);
}
}));
AddAction("/muteToggle", (id, content) => 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) => AddAction("/volumeDown", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) =>
{ {
@@ -89,7 +98,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
try try
{ {
device.VolumeDown(b); _localDevice.VolumeDown(b);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -97,38 +106,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
})); }));
if (!(device is IBasicVolumeWithFeedback feedback)) _localDevice.MuteFeedback.OutputChange += (sender, args) =>
{
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) =>
{ {
PostStatusMessage(JToken.FromObject( PostStatusMessage(JToken.FromObject(
new new
@@ -141,10 +119,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
); );
}; };
feedback.VolumeLevelFeedback.OutputChange += (sender, args) => _localDevice.VolumeLevelFeedback.OutputChange += (sender, args) =>
{ {
var rawValue = ""; var rawValue = "";
if (feedback is IBasicVolumeWithFeedbackAdvanced volumeAdvanced) if (_localDevice is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
{ {
rawValue = volumeAdvanced.RawVolumeLevel.ToString(); rawValue = volumeAdvanced.RawVolumeLevel.ToString();
} }
@@ -160,6 +138,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostStatusMessage(JToken.FromObject(message)); PostStatusMessage(JToken.FromObject(message));
}; };
} }
#endregion #endregion

View File

@@ -7,29 +7,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
public class GenericMessenger : MessengerBase 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) public GenericMessenger(string key, EssentialsDevice device, string messagePath) : base(key, messagePath, device)
{ {
} }
/// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
base.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(); 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 Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -13,12 +13,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
private readonly IBasicVideoMuteWithFeedback device; 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) public IBasicVideoMuteWithFeedbackMessenger(string key, string messagePath, IBasicVideoMuteWithFeedback device)
: base(key, messagePath, device as IKeyName) : base(key, messagePath, device as IKeyName)
{ {
@@ -28,24 +22,21 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary> /// <summary>
/// SendFullStatus method /// SendFullStatus method
/// </summary> /// </summary>
public void SendFullStatus(string id = null) public void SendFullStatus()
{ {
var messageObj = new IBasicVideoMuteWithFeedbackMessage var messageObj = new IBasicVideoMuteWithFeedbackMessage
{ {
VideoMuteState = device.VideoMuteIsOn.BoolValue VideoMuteState = device.VideoMuteIsOn.BoolValue
}; };
PostStatusMessage(messageObj, id); PostStatusMessage(messageObj);
} }
/// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id)); AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/videoMuteStatus", (id, content) => SendFullStatus(id));
AddAction("/videoMuteToggle", (id, content) => AddAction("/videoMuteToggle", (id, content) =>
{ {

View File

@@ -24,12 +24,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
AddAction("/fullStatus", (id, content) => AddAction("/fullStatus", (id, content) =>
{ {
SendFullStatus(id); PostStatusMessage(new CommunicationMonitorState
}); {
CommunicationMonitor = new CommunicationMonitorProps
AddAction("/commStatus", (id, content) => {
{ IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline,
SendFullStatus(id); Status = _communicationMonitor.CommunicationMonitor.Status
}
});
}); });
_communicationMonitor.CommunicationMonitor.StatusChange += (sender, args) => _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> /// <summary>

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic; using Newtonsoft.Json;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -22,9 +22,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); 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) => 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> /// <summary>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,9 +1,9 @@
using System.Collections.Generic; using Newtonsoft.Json;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -13,7 +13,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
public class ILevelControlsMessenger : MessengerBase public class ILevelControlsMessenger : MessengerBase
{ {
private ILevelControls levelControlsDevice; private ILevelControls levelControlsDevice;
public ILevelControlsMessenger(string key, string messagePath, ILevelControls device) : base(key, messagePath, device as IKeyName) public ILevelControlsMessenger(string key, string messagePath, ILevelControls device) : base(key, messagePath, device as IKeyName)
{ {
levelControlsDevice = device; levelControlsDevice = device;
@@ -23,9 +22,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); 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) 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> /// <summary>

View File

@@ -1,12 +1,12 @@
using System; using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Core.Routing;
using Serilog.Events; using Serilog.Events;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -25,9 +25,25 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); 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) => 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> /// <summary>

View File

@@ -1,9 +1,9 @@
using System; using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -14,28 +14,17 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
private readonly IProjectorScreenLiftControl device; 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) public IProjectorScreenLiftControlMessenger(string key, string messagePath, IProjectorScreenLiftControl screenLiftDevice)
: base(key, messagePath, screenLiftDevice as IKeyName) : base(key, messagePath, screenLiftDevice as IKeyName)
{ {
device = screenLiftDevice; device = screenLiftDevice;
} }
/// <summary>
/// Registers the actions for the messenger.
/// </summary>
protected override void RegisterActions() protected override void RegisterActions()
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id)); AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/screenliftStatus", (id, content) => SendFullStatus(id));
AddAction("/raise", (id, content) => AddAction("/raise", (id, content) =>
{ {
@@ -64,7 +53,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostStatusMessage(JToken.FromObject(state)); PostStatusMessage(JToken.FromObject(state));
} }
private void SendFullStatus(string id = null) private void SendFullStatus()
{ {
var state = new ScreenLiftStateMessage var state = new ScreenLiftStateMessage
{ {
@@ -73,7 +62,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
DisplayDeviceKey = device.DisplayDeviceKey DisplayDeviceKey = device.DisplayDeviceKey
}; };
PostStatusMessage(state, id); PostStatusMessage(state);
} }
} }
@@ -82,23 +71,20 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
public class ScreenLiftStateMessage : DeviceStateMessageBase public class ScreenLiftStateMessage : DeviceStateMessageBase
{ {
/// <summary>
/// Gets or sets the InUpPosition
/// </summary>
[JsonProperty("inUpPosition", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("inUpPosition", NullValueHandling = NullValueHandling.Ignore)]
public bool? InUpPosition { get; set; } public bool? InUpPosition { get; set; }
[JsonProperty("displayDeviceKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the DisplayDeviceKey /// Gets or sets the DisplayDeviceKey
/// </summary> /// </summary>
[JsonProperty("displayDeviceKey", NullValueHandling = NullValueHandling.Ignore)]
public string DisplayDeviceKey { get; set; } public string DisplayDeviceKey { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Type /// Gets or sets the Type
/// </summary> /// </summary>
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
public eScreenLiftControlType Type { get; set; } 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;
using PepperDash.Core.Logging; using PepperDash.Core.Logging;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using System;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
@@ -36,9 +36,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
protected override void RegisterActions() protected override void RegisterActions()
{ {
AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject(id)); AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject());
AddAction("/routingStatus", (id, content) => SendRoutingFullMessageObject(id));
AddAction("/source", (id, content) => AddAction("/source", (id, content) =>
{ {
@@ -64,7 +62,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary> /// <summary>
/// Helper method to update full status of the routing device /// Helper method to update full status of the routing device
/// </summary> /// </summary>
private void SendRoutingFullMessageObject(string id = null) private void SendRoutingFullMessageObject()
{ {
if (RoutingDevice is IRoutingSink sinkDevice) if (RoutingDevice is IRoutingSink sinkDevice)
{ {
@@ -86,10 +84,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
public class RoutingStateMessage : DeviceStateMessageBase public class RoutingStateMessage : DeviceStateMessageBase
{ {
[JsonProperty("selectedSourceKey")]
/// <summary> /// <summary>
/// Gets or sets the SelectedSourceKey /// Gets or sets the SelectedSourceKey
/// </summary> /// </summary>
[JsonProperty("selectedSourceKey")]
public string SelectedSourceKey { get; set; } public string SelectedSourceKey { get; set; }
} }
} }

View File

@@ -1,9 +1,9 @@
using System; using Newtonsoft.Json;
using System.Collections.Generic;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging; using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -11,13 +11,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// Represents a ISelectableItemsMessenger /// Represents a ISelectableItemsMessenger
/// </summary> /// </summary>
public class ISelectableItemsMessenger<TKey> : MessengerBase public class ISelectableItemsMessenger<TKey> : MessengerBase
{ {
private readonly ISelectableItems<TKey> itemDevice; private readonly ISelectableItems<TKey> itemDevice;
private readonly string _propName; private readonly string _propName;
private List<string> _itemKeys = new List<string>();
/// <summary> /// <summary>
/// Constructs a messenger for a device that implements ISelectableItems<typeparamref name="TKey"/> /// Constructs a messenger for a device that implements ISelectableItems<typeparamref name="TKey"/>
/// </summary> /// </summary>
@@ -36,14 +34,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, context) => AddAction("/fullStatus", (id, context) =>
SendFullStatus(id) {
); SendFullStatus();
});
AddAction("/itemsStatus", (id, content) => SendFullStatus(id));
itemDevice.ItemsUpdated += (sender, args) => itemDevice.ItemsUpdated += (sender, args) =>
{ {
SetItems(); SendFullStatus();
}; };
itemDevice.CurrentItemChanged += (sender, args) => itemDevice.CurrentItemChanged += (sender, args) =>
@@ -51,22 +48,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
SendFullStatus(); SendFullStatus();
}; };
SetItems();
}
/// <summary>
/// Sets the items and registers their update events
/// </summary>
private void SetItems()
{
/// Clear out any existing item actions
foreach (var item in _itemKeys)
{
RemoveAction($"/{item}");
}
_itemKeys.Clear();
foreach (var input in itemDevice.Items) foreach (var input in itemDevice.Items)
{ {
var key = input.Key; var key = input.Key;
@@ -77,19 +58,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
localItem.Select(); localItem.Select();
}); });
_itemKeys.Add(key.ToString()); localItem.ItemUpdated += (sender, args) =>
{
localItem.ItemUpdated -= LocalItem_ItemUpdated; SendFullStatus();
localItem.ItemUpdated += LocalItem_ItemUpdated; };
} }
} }
private void LocalItem_ItemUpdated(object sender, EventArgs e) private void SendFullStatus()
{
SendFullStatus();
}
private void SendFullStatus(string id = null)
{ {
try try
{ {
@@ -101,7 +77,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
CurrentItem = itemDevice.CurrentItem CurrentItem = itemDevice.CurrentItem
}; };
PostStatusMessage(stateObject, id); PostStatusMessage(stateObject);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -115,17 +91,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
public class ISelectableItemsStateMessage<TKey> : DeviceStateMessageBase public class ISelectableItemsStateMessage<TKey> : DeviceStateMessageBase
{ {
/// <summary>
/// Gets or sets the Items
/// </summary>
[JsonProperty("items")] [JsonProperty("items")]
public Dictionary<TKey, ISelectableItem> Items { get; set; } public Dictionary<TKey, ISelectableItem> Items { get; set; }
[JsonProperty("currentItem")]
/// <summary> /// <summary>
/// Gets or sets the CurrentItem /// Gets or sets the CurrentItem
/// </summary> /// </summary>
[JsonProperty("currentItem")]
public TKey CurrentItem { get; set; } public TKey CurrentItem { get; set; }
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,45 +1,26 @@
using System; using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp.Net;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging; using PepperDash.Core.Logging;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
/// <summary> /// <summary>
/// Provides a messaging bridge /// Provides a messaging bridge
/// </summary> /// </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; 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 List<string> _deviceInterfaces;
private readonly Dictionary<string, Action<string, JToken>> _actions = new Dictionary<string, Action<string, JToken>>(); private readonly Dictionary<string, Action<string, JToken>> _actions = new Dictionary<string, Action<string, JToken>>();
/// <summary>
/// Gets the DeviceKey
/// </summary>
public string DeviceKey => _device?.Key ?? ""; public string DeviceKey => _device?.Key ?? "";
@@ -69,12 +50,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
MessagePath = messagePath; 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) protected MessengerBase(string key, string messagePath, IKeyName device)
: this(key, messagePath) : this(key, messagePath)
{ {
@@ -106,21 +81,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
RegisterActions(); 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) private void HandleMessage(string path, string id, JToken content)
{ {
// replace base path with empty string. Should leave something like /fullStatus // replace base path with empty string. Should leave something like /fullStatus
@@ -131,20 +91,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
return; 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); 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) protected void AddAction(string path, Action<string, JToken> action)
{ {
if (_actions.ContainsKey(path)) if (_actions.ContainsKey(path))
{ {
//Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, $"Messenger {Key} already has action registered at {path}", this);
return; return;
} }
@@ -159,10 +115,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
return _actions.Keys.ToList(); return _actions.Keys.ToList();
} }
/// <summary>
/// Removes an action for a given path
/// </summary>
/// <param name="path"></param>
protected void RemoveAction(string path) protected void RemoveAction(string path)
{ {
if (!_actions.ContainsKey(path)) if (!_actions.ContainsKey(path))
@@ -176,62 +128,17 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary> /// <summary>
/// Implemented in extending classes. Wire up API calls and feedback here /// Implemented in extending classes. Wire up API calls and feedback here
/// </summary> /// </summary>
/// <param name="appServerController"></param>
protected virtual void RegisterActions() 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> /// <summary>
/// Helper for posting status message /// Helper for posting status message
/// </summary> /// </summary>
/// <param name="type"></param>
/// <param name="message"></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) protected void PostStatusMessage(DeviceStateMessageBase message, string clientId = null)
{ {
try try
@@ -252,22 +159,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
message.Name = _device.Name; message.Name = _device.Name;
var token = JToken.FromObject(message); var token = JToken.FromObject(message);
PostStatusMessage(token, MessagePath, clientId); PostStatusMessage(token, MessagePath, clientId);
} }
catch (Exception ex) 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) protected void PostStatusMessage(string type, DeviceStateMessageBase deviceState, string clientId = null)
{ {
try try
@@ -287,54 +188,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
catch (Exception ex) 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) protected void PostStatusMessage(JToken content, string type = "", string clientId = null)
{ {
try 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 }); AppServerController?.SendMessageObject(new MobileControlMessage { Type = !string.IsNullOrEmpty(type) ? type : MessagePath, ClientId = clientId, Content = content });
} }
catch (Exception ex) catch (Exception ex)
{ {
this.LogError("Exception posting status message: {message}", ex.Message); Debug.LogMessage(ex, "Exception posting status message", this);
this.LogDebug(ex, "Stack Trace: ");
} }
} }
/// <summary>
/// Helper for posting event message
/// </summary>
/// <param name="message"></param>
protected void PostEventMessage(DeviceEventMessageBase message) protected void PostEventMessage(DeviceEventMessageBase message)
{ {
message.Key = _device.Key; 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) protected void PostEventMessage(DeviceEventMessageBase message, string eventType)
{ {
message.Key = _device.Key; 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) protected void PostEventMessage(string eventType)
{ {
AppServerController?.SendMessageObject(new MobileControlMessage 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 Crestron.SimplSharp;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
/// <summary>
/// Handler for press/hold/release messages
/// </summary>
public static class PressAndHoldHandler public static class PressAndHoldHandler
{ {
private const long ButtonHeartbeatInterval = 1000; private const long ButtonHeartbeatInterval = 1000;
@@ -29,21 +26,21 @@ namespace PepperDash.Essentials.AppServer.Messengers
private static void AddTimer(string deviceKey, Action<bool> action) 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)) 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; 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); action(true);
cancelTimer = new CTimer(o => cancelTimer = new CTimer(o =>
{ {
Debug.LogDebug("Timer expired for {deviceKey}", deviceKey); Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Timer expired for {deviceKey}", deviceKey);
action(false); action(false);
@@ -55,30 +52,30 @@ namespace PepperDash.Essentials.AppServer.Messengers
private static void ResetTimer(string deviceKey, Action<bool> action) 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)) 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; 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); cancelTimer.Reset(ButtonHeartbeatInterval);
} }
private static void StopTimer(string deviceKey, Action<bool> action) 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)) 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; 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); action(false);
cancelTimer.Stop(); cancelTimer.Stop();
@@ -87,15 +84,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
public static Action<string, Action<bool>> GetPressAndHoldHandler(string value) 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)) 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; return null;
} }
Debug.LogDebug("Got handler for {value}", value); Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Got handler for {value}", value);
return handler; return handler;
} }
@@ -107,7 +104,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
var msg = content.ToObject<MobileControlSimpleContent<string>>(); 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); var timerHandler = GetPressAndHoldHandler(msg.Value);

View File

@@ -1,10 +1,10 @@
using System; using Newtonsoft.Json;
using System.Collections.Generic;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging; using PepperDash.Core.Logging;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Room.Config;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -31,14 +31,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
var events = _room.GetScheduledEvents(); var events = _room.GetScheduledEvents();
SendFullStatus(events, id); SendFullStatus(events);
});
AddAction("/scheduledEventsStatus", (id, content) =>
{
var events = _room.GetScheduledEvents();
SendFullStatus(events, id);
}); });
_room.ScheduledEventsChanged += (sender, args) => SendFullStatus(args.ScheduledEvents); _room.ScheduledEventsChanged += (sender, args) => SendFullStatus(args.ScheduledEvents);
@@ -62,11 +55,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
catch (Exception ex) 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 var message = new RoomEventScheduleStateMessage
@@ -74,7 +67,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
ScheduleEvents = events, 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.Core;
using PepperDash.Essentials.Core.Shades; using PepperDash.Essentials.Core.Shades;
using System;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -22,8 +22,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus(id)); AddAction("/fullStatus", (id, content) => SendFullStatus());
AddAction("/shadesStatus", (id, content) => SendFullStatus(id));
AddAction("/shadeUp", (id, content) => 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(); var state = new ShadeBaseStateMessage();
@@ -86,7 +85,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
state.IsClosed = feedbackDevice.ShadeIsClosedFeedback.BoolValue; state.IsClosed = feedbackDevice.ShadeIsClosedFeedback.BoolValue;
} }
PostStatusMessage(state, id); PostStatusMessage(state);
} }
} }
@@ -95,11 +94,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
public class ShadeBaseStateMessage : DeviceStateMessageBase public class ShadeBaseStateMessage : DeviceStateMessageBase
{ {
[JsonProperty("middleButtonLabel", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the MiddleButtonLabel /// Gets or sets the MiddleButtonLabel
/// </summary> /// </summary>
[JsonProperty("middleButtonLabel", NullValueHandling = NullValueHandling.Ignore)]
public string MiddleButtonLabel { get; set; } public string MiddleButtonLabel { get; set; }
[JsonProperty("isOpen", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("isOpen", NullValueHandling = NullValueHandling.Ignore)]

View File

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

View File

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

View File

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

View File

@@ -33,7 +33,7 @@
<Compile Remove="Messengers\SIMPLVtcMessenger.cs" /> <Compile Remove="Messengers\SIMPLVtcMessenger.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" /> <PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.157" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\PepperDash.Core\PepperDash.Core.csproj" /> <ProjectReference Include="..\PepperDash.Core\PepperDash.Core.csproj" />

View File

@@ -7,18 +7,16 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public class AuthorizationResponse public class AuthorizationResponse
{ {
[JsonProperty("authorized")]
/// <summary> /// <summary>
/// Gets or sets the Authorized /// Gets or sets the Authorized
/// </summary> /// </summary>
[JsonProperty("authorized")]
public bool Authorized { get; set; } public bool Authorized { get; set; }
[JsonProperty("reason", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Reason /// Gets or sets the Reason
/// </summary> /// </summary>
[JsonProperty("reason", NullValueHandling = NullValueHandling.Ignore)]
public string Reason { get; set; } = null; public string Reason { get; set; } = null;
} }
@@ -27,11 +25,10 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public class AuthorizationRequest public class AuthorizationRequest
{ {
[JsonProperty("grantCode")]
/// <summary> /// <summary>
/// Gets or sets the GrantCode /// Gets or sets the GrantCode
/// </summary> /// </summary>
[JsonProperty("grantCode")]
public string GrantCode { get; set; } 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> /// </summary>
[JsonProperty("enableApiServer")] [JsonProperty("enableApiServer")]
public bool EnableApiServer { get; set; } = true; public bool EnableApiServer { get; set; } = true;
/// <summary>
/// Enable subscriptions for Messengers
/// </summary>
[JsonProperty("enableMessengerSubscriptions")]
public bool EnableMessengerSubscriptions { get; set; }
} }
/// <summary> /// <summary>
@@ -84,15 +78,6 @@ namespace PepperDash.Essentials
[JsonProperty("csLanUiDeviceKeys")] [JsonProperty("csLanUiDeviceKeys")]
public List<string> CSLanUiDeviceKeys { get; set; } 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> /// <summary>
/// Initializes a new instance of the MobileControlDirectServerPropertiesConfig class. /// Initializes a new instance of the MobileControlDirectServerPropertiesConfig class.
/// </summary> /// </summary>

View File

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

View File

@@ -54,10 +54,7 @@ namespace PepperDash.Essentials
StringComparer.InvariantCultureIgnoreCase StringComparer.InvariantCultureIgnoreCase
); );
/// <summary> public Dictionary<string, List<IMobileControlAction>> ActionDictionary => _actionDictionary;
/// Actions
/// </summary>
public ReadOnlyDictionary<string, List<IMobileControlAction>> ActionDictionary => new ReadOnlyDictionary<string, List<IMobileControlAction>>(_actionDictionary);
private readonly GenericQueue _receiveQueue; private readonly GenericQueue _receiveQueue;
private readonly List<MobileControlBridgeBase> _roomBridges = private readonly List<MobileControlBridgeBase> _roomBridges =
@@ -69,16 +66,6 @@ namespace PepperDash.Essentials
private readonly Dictionary<string, IMobileControlMessenger> _defaultMessengers = private readonly Dictionary<string, IMobileControlMessenger> _defaultMessengers =
new Dictionary<string, IMobileControlMessenger>(); 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 _transmitToServerQueue;
private readonly GenericQueue _transmitToClientsQueue; private readonly GenericQueue _transmitToClientsQueue;
@@ -257,7 +244,7 @@ namespace PepperDash.Essentials
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment.ProgramStatusEventHandler +=
CrestronEnvironment_ProgramStatusEventHandler; CrestronEnvironment_ProgramStatusEventHandler;
ApiOnlineAndAuthorized = new BoolFeedback("apiOnlineAndAuthorized", () => ApiOnlineAndAuthorized = new BoolFeedback(() =>
{ {
if (_wsClient2 == null) if (_wsClient2 == null)
return false; return false;
@@ -405,15 +392,14 @@ namespace PepperDash.Essentials
messengerAdded = true; messengerAdded = true;
} }
// Default to IHasCameraControls if CameraBase and IHasCameraControls if (device is CameraBase cameraDevice)
if (device is CameraBase cameraDevice && !(device is IHasCameraControls))
{ {
this.LogVerbose( this.LogVerbose(
"Adding CameraBaseMessenger for {deviceKey}", "Adding CameraBaseMessenger for {deviceKey}",
device.Key device.Key
); );
var cameraMessenger = new CameraBaseMessenger<CameraBase>( var cameraMessenger = new CameraBaseMessenger(
$"{device.Key}-cameraBase-{Key}", $"{device.Key}-cameraBase-{Key}",
cameraDevice, cameraDevice,
$"/device/{device.Key}" $"/device/{device.Key}"
@@ -424,21 +410,6 @@ namespace PepperDash.Essentials
messengerAdded = true; 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) if (device is BlueJeansPc)
{ {
this.LogVerbose( this.LogVerbose(
@@ -515,15 +486,15 @@ namespace PepperDash.Essentials
messengerAdded = true; messengerAdded = true;
} }
if (device is IBasicVolumeControls) if (device is IBasicVolumeWithFeedback)
{ {
var deviceKey = device.Key; var deviceKey = device.Key;
this.LogVerbose( this.LogVerbose(
"Adding IBasicVolumeControls for {deviceKey}", "Adding IBasicVolumeControlWithFeedback for {deviceKey}",
deviceKey deviceKey
); );
var volControlDevice = device as IBasicVolumeControls; var volControlDevice = device as IBasicVolumeWithFeedback;
var messenger = new DeviceVolumeMessenger( var messenger = new DeviceVolumeMessenger(
$"{device.Key}-volume-{Key}", $"{device.Key}-volume-{Key}",
string.Format("/device/{0}", deviceKey), string.Format("/device/{0}", deviceKey),
@@ -991,19 +962,6 @@ namespace PepperDash.Essentials
messengerAdded = true; 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); this.LogVerbose("Trying to cast to generic device for device: {key}", device.Key);
if (device is EssentialsDevice) if (device is EssentialsDevice)
@@ -1241,7 +1199,8 @@ namespace PepperDash.Essentials
if (_initialized) 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 messenger.MessagePath
); );
if (messenger is IMobileControlMessengerWithSubscriptions subMessenger)
{
subMessenger.RegisterWithAppServer(this, Config.EnableMessengerSubscriptions);
return;
}
messenger.RegisterWithAppServer(this); messenger.RegisterWithAppServer(this);
} }
@@ -1382,30 +1335,11 @@ namespace PepperDash.Essentials
{ {
Log = Log =
{ {
Output = (data, message) => Output = (data, s) =>
{ this.LogDebug(
switch (data.Level) "Message from websocket: {message}",
{ data
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;
}
}
} }
}; };
@@ -1449,13 +1383,13 @@ namespace PepperDash.Essentials
private void SetWebsocketDebugLevel(string cmdparameters) private void SetWebsocketDebugLevel(string cmdparameters)
{ {
// if (CrestronEnvironment.ProgramCompatibility == eCrestronSeries.Series4) if (CrestronEnvironment.ProgramCompatibility == eCrestronSeries.Series4)
// { {
// this.LogInformation( this.LogInformation(
// "Setting websocket log level not currently allowed on 4 series." "Setting websocket log level not currently allowed on 4 series."
// ); );
// return; // Web socket log level not currently allowed in series4 return; // Web socket log level not currently allowed in series4
// } }
if (string.IsNullOrEmpty(cmdparameters)) if (string.IsNullOrEmpty(cmdparameters))
{ {
@@ -1481,8 +1415,6 @@ namespace PepperDash.Essentials
_wsClient2.Log.Level = _wsLogLevel; _wsClient2.Log.Level = _wsLogLevel;
} }
_directServer?.SetWebsocketLogLevel(_wsLogLevel);
CrestronConsole.ConsoleCommandResponse($"Websocket log level set to {debugLevel}"); CrestronConsole.ConsoleCommandResponse($"Websocket log level set to {debugLevel}");
} }
catch catch
@@ -1552,7 +1484,7 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// Adds an action to the dictionary /// Adds an action to the dictionary
/// </summary> /// </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> /// <param name="action">The action to be triggered by the commmand</param>
public void AddAction<T>(T messenger, Action<string, string, JToken> action) public void AddAction<T>(T messenger, Action<string, string, JToken> action)
where T : IMobileControlMessenger where T : IMobileControlMessenger
@@ -2262,21 +2194,8 @@ namespace PepperDash.Essentials
return; 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)) if (!_roomCombiner.CurrentScenario.UiMap.ContainsKey(roomKey))
{ {
this.LogWarning( this.LogWarning(
"Unable to find correct roomKey for {roomKey} in current scenario. Returning {roomKey} as roomKey", roomKey); "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"); 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

@@ -38,7 +38,7 @@
<Compile Remove="RoomBridges\SourceDeviceMapDictionary.cs" /> <Compile Remove="RoomBridges\SourceDeviceMapDictionary.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" /> <PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.157" />
<PackageReference Include="WebSocketSharp-netstandard" Version="1.0.1" /> <PackageReference Include="WebSocketSharp-netstandard" Version="1.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -1,7 +1,4 @@
using System; using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
@@ -20,6 +17,9 @@ using PepperDash.Essentials.Devices.Common.Room;
using PepperDash.Essentials.Devices.Common.VideoCodec; using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.WebSocketServer; using PepperDash.Essentials.WebSocketServer;
using System;
using System.Collections.Generic;
using System.Linq;
using IShades = PepperDash.Essentials.Core.Shades.IShades; using IShades = PepperDash.Essentials.Core.Shades.IShades;
using ShadeBase = PepperDash.Essentials.Devices.Common.Shades.ShadeBase; 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 /// Sends the full status of the room to the server
/// </summary> /// </summary>
/// <param name="room"></param> /// <param name="room"></param>
/// <param name="id"></param>
private void SendFullStatusForClientId(string id, IEssentialsRoom room) private void SendFullStatusForClientId(string id, IEssentialsRoom room)
{ {
//Parent.SendMessageObject(GetFullStatus(room)); //Parent.SendMessageObject(GetFullStatus(room));
@@ -555,7 +554,6 @@ namespace PepperDash.Essentials.RoomBridges
/// <summary> /// <summary>
/// Determines the configuration of the room and the details about the devices associated with the room /// Determines the configuration of the room and the details about the devices associated with the room
/// </summary>
/// <param name="room"></param> /// <param name="room"></param>
/// <returns></returns> /// <returns></returns>
private RoomConfiguration GetRoomConfiguration(IEssentialsRoom room) private RoomConfiguration GetRoomConfiguration(IEssentialsRoom room)
@@ -800,38 +798,31 @@ namespace PepperDash.Essentials.RoomBridges
/// </summary> /// </summary>
public class RoomStateMessage : DeviceStateMessageBase public class RoomStateMessage : DeviceStateMessageBase
{ {
[JsonProperty("configuration", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Configuration /// Gets or sets the Configuration
/// </summary> /// </summary>
[JsonProperty("configuration", NullValueHandling = NullValueHandling.Ignore)]
public RoomConfiguration Configuration { get; set; } public RoomConfiguration Configuration { get; set; }
[JsonProperty("activityMode", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("activityMode", NullValueHandling = NullValueHandling.Ignore)]
public int? ActivityMode { get; set; } public int? ActivityMode { get; set; }
[JsonProperty("advancedSharingActive", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("advancedSharingActive", NullValueHandling = NullValueHandling.Ignore)]
public bool? AdvancedSharingActive { get; set; } public bool? AdvancedSharingActive { get; set; }
[JsonProperty("isOn", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("isOn", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsOn { get; set; } public bool? IsOn { get; set; }
[JsonProperty("isWarmingUp", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("isWarmingUp", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsWarmingUp { get; set; } public bool? IsWarmingUp { get; set; }
[JsonProperty("isCoolingDown", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("isCoolingDown", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsCoolingDown { get; set; } public bool? IsCoolingDown { get; set; }
[JsonProperty("selectedSourceKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the SelectedSourceKey /// Gets or sets the SelectedSourceKey
/// </summary> /// </summary>
[JsonProperty("selectedSourceKey", NullValueHandling = NullValueHandling.Ignore)]
public string SelectedSourceKey { get; set; } public string SelectedSourceKey { get; set; }
[JsonProperty("share", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Share /// Gets or sets the Share
/// </summary> /// </summary>
[JsonProperty("share", NullValueHandling = NullValueHandling.Ignore)]
public ShareState Share { get; set; } public ShareState Share { get; set; }
[JsonProperty("volumes", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("volumes", NullValueHandling = NullValueHandling.Ignore)]
@@ -846,16 +837,13 @@ namespace PepperDash.Essentials.RoomBridges
/// </summary> /// </summary>
public class ShareState public class ShareState
{ {
[JsonProperty("currentShareText", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the CurrentShareText /// Gets or sets the CurrentShareText
/// </summary> /// </summary>
[JsonProperty("currentShareText", NullValueHandling = NullValueHandling.Ignore)]
public string CurrentShareText { get; set; } public string CurrentShareText { get; set; }
[JsonProperty("enabled", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("enabled", NullValueHandling = NullValueHandling.Ignore)]
public bool? Enabled { get; set; } public bool? Enabled { get; set; }
[JsonProperty("isSharing", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("isSharing", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsSharing { get; set; } public bool? IsSharing { get; set; }
} }
@@ -865,156 +853,131 @@ namespace PepperDash.Essentials.RoomBridges
/// </summary> /// </summary>
public class RoomConfiguration public class RoomConfiguration
{ {
//[JsonProperty("shutdownPromptSeconds", NullValueHandling = NullValueHandling.Ignore)]
//public int? ShutdownPromptSeconds { get; set; }
[JsonProperty("hasVideoConferencing", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasVideoConferencing", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasVideoConferencing { get; set; } public bool? HasVideoConferencing { get; set; }
[JsonProperty("videoCodecIsZoomRoom", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("videoCodecIsZoomRoom", NullValueHandling = NullValueHandling.Ignore)]
public bool? VideoCodecIsZoomRoom { get; set; } public bool? VideoCodecIsZoomRoom { get; set; }
[JsonProperty("hasAudioConferencing", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasAudioConferencing", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasAudioConferencing { get; set; } public bool? HasAudioConferencing { get; set; }
[JsonProperty("hasEnvironmentalControls", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasEnvironmentalControls", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasEnvironmentalControls { get; set; } public bool? HasEnvironmentalControls { get; set; }
[JsonProperty("hasCameraControls", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasCameraControls", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasCameraControls { get; set; } public bool? HasCameraControls { get; set; }
[JsonProperty("hasSetTopBoxControls", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasSetTopBoxControls", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasSetTopBoxControls { get; set; } public bool? HasSetTopBoxControls { get; set; }
[JsonProperty("hasRoutingControls", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasRoutingControls", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasRoutingControls { get; set; } public bool? HasRoutingControls { get; set; }
[JsonProperty("touchpanelKeys", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the TouchpanelKeys /// Gets or sets the TouchpanelKeys
/// </summary> /// </summary>
[JsonProperty("touchpanelKeys", NullValueHandling = NullValueHandling.Ignore)]
public List<string> TouchpanelKeys { get; set; } public List<string> TouchpanelKeys { get; set; }
[JsonProperty("zoomRoomControllerKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the ZoomRoomControllerKey /// Gets or sets the ZoomRoomControllerKey
/// </summary> /// </summary>
[JsonProperty("zoomRoomControllerKey", NullValueHandling = NullValueHandling.Ignore)]
public string ZoomRoomControllerKey { get; set; } public string ZoomRoomControllerKey { get; set; }
[JsonProperty("ciscoNavigatorKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the CiscoNavigatorKey /// Gets or sets the CiscoNavigatorKey
/// </summary> /// </summary>
[JsonProperty("ciscoNavigatorKey", NullValueHandling = NullValueHandling.Ignore)]
public string CiscoNavigatorKey { get; set; } public string CiscoNavigatorKey { get; set; }
[JsonProperty("videoCodecKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the VideoCodecKey /// Gets or sets the VideoCodecKey
/// </summary> /// </summary>
[JsonProperty("videoCodecKey", NullValueHandling = NullValueHandling.Ignore)]
public string VideoCodecKey { get; set; } public string VideoCodecKey { get; set; }
[JsonProperty("audioCodecKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the AudioCodecKey /// Gets or sets the AudioCodecKey
/// </summary> /// </summary>
[JsonProperty("audioCodecKey", NullValueHandling = NullValueHandling.Ignore)]
public string AudioCodecKey { get; set; } public string AudioCodecKey { get; set; }
[JsonProperty("matrixRoutingKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the MatrixRoutingKey /// Gets or sets the MatrixRoutingKey
/// </summary> /// </summary>
[JsonProperty("matrixRoutingKey", NullValueHandling = NullValueHandling.Ignore)]
public string MatrixRoutingKey { get; set; } public string MatrixRoutingKey { get; set; }
[JsonProperty("endpointKeys", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the EndpointKeys /// Gets or sets the EndpointKeys
/// </summary> /// </summary>
[JsonProperty("endpointKeys", NullValueHandling = NullValueHandling.Ignore)]
public List<string> EndpointKeys { get; set; } public List<string> EndpointKeys { get; set; }
[JsonProperty("accessoryDeviceKeys", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the AccessoryDeviceKeys /// Gets or sets the AccessoryDeviceKeys
/// </summary> /// </summary>
[JsonProperty("accessoryDeviceKeys", NullValueHandling = NullValueHandling.Ignore)]
public List<string> AccessoryDeviceKeys { get; set; } public List<string> AccessoryDeviceKeys { get; set; }
[JsonProperty("defaultDisplayKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the DefaultDisplayKey /// Gets or sets the DefaultDisplayKey
/// </summary> /// </summary>
[JsonProperty("defaultDisplayKey", NullValueHandling = NullValueHandling.Ignore)]
public string DefaultDisplayKey { get; set; } public string DefaultDisplayKey { get; set; }
[JsonProperty("destinations", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("destinations", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<eSourceListItemDestinationTypes, string> Destinations { get; set; } public Dictionary<eSourceListItemDestinationTypes, string> Destinations { get; set; }
[JsonProperty("environmentalDevices", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the EnvironmentalDevices /// Gets or sets the EnvironmentalDevices
/// </summary> /// </summary>
[JsonProperty("environmentalDevices", NullValueHandling = NullValueHandling.Ignore)]
public List<EnvironmentalDeviceConfiguration> EnvironmentalDevices { get; set; } public List<EnvironmentalDeviceConfiguration> EnvironmentalDevices { get; set; }
[JsonProperty("sourceList", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("sourceList", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, SourceListItem> SourceList { get; set; } public Dictionary<string, SourceListItem> SourceList { get; set; }
[JsonProperty("destinationList", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("destinationList", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, DestinationListItem> DestinationList { get; set; } public Dictionary<string, DestinationListItem> DestinationList { get; set; }
[JsonProperty("audioControlPointList", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the AudioControlPointList /// Gets or sets the AudioControlPointList
/// </summary> /// </summary>
[JsonProperty("audioControlPointList", NullValueHandling = NullValueHandling.Ignore)]
public AudioControlPointListItem AudioControlPointList { get; set; } public AudioControlPointListItem AudioControlPointList { get; set; }
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, CameraListItem> CameraList { get; set; } public Dictionary<string, CameraListItem> CameraList { get; set; }
[JsonProperty("defaultPresentationSourceKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the DefaultPresentationSourceKey /// Gets or sets the DefaultPresentationSourceKey
/// </summary> /// </summary>
[JsonProperty("defaultPresentationSourceKey", NullValueHandling = NullValueHandling.Ignore)]
public string DefaultPresentationSourceKey { get; set; } public string DefaultPresentationSourceKey { get; set; }
[JsonProperty("helpMessage", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the HelpMessage /// Gets or sets the HelpMessage
/// </summary> /// </summary>
[JsonProperty("helpMessage", NullValueHandling = NullValueHandling.Ignore)]
public string HelpMessage { get; set; } public string HelpMessage { get; set; }
[JsonProperty("techPassword", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the TechPassword /// Gets or sets the TechPassword
/// </summary> /// </summary>
[JsonProperty("techPassword", NullValueHandling = NullValueHandling.Ignore)]
public string TechPassword { get; set; } public string TechPassword { get; set; }
[JsonProperty("uiBehavior", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the UiBehavior /// Gets or sets the UiBehavior
/// </summary> /// </summary>
[JsonProperty("uiBehavior", NullValueHandling = NullValueHandling.Ignore)]
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; } public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
[JsonProperty("supportsAdvancedSharing", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("supportsAdvancedSharing", NullValueHandling = NullValueHandling.Ignore)]
public bool? SupportsAdvancedSharing { get; set; } public bool? SupportsAdvancedSharing { get; set; }
[JsonProperty("userCanChangeShareMode", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("userCanChangeShareMode", NullValueHandling = NullValueHandling.Ignore)]
public bool? UserCanChangeShareMode { get; set; } public bool? UserCanChangeShareMode { get; set; }
[JsonProperty("roomCombinerKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the RoomCombinerKey /// Gets or sets the RoomCombinerKey
/// </summary> /// </summary>
[JsonProperty("roomCombinerKey", NullValueHandling = NullValueHandling.Ignore)]
public string RoomCombinerKey { get; set; } public string RoomCombinerKey { get; set; }
public RoomConfiguration() public RoomConfiguration()
@@ -1031,19 +994,17 @@ namespace PepperDash.Essentials.RoomBridges
/// </summary> /// </summary>
public class EnvironmentalDeviceConfiguration public class EnvironmentalDeviceConfiguration
{ {
[JsonProperty("deviceKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the DeviceKey /// Gets or sets the DeviceKey
/// </summary> /// </summary>
[JsonProperty("deviceKey", NullValueHandling = NullValueHandling.Ignore)]
public string DeviceKey { get; private set; } public string DeviceKey { get; private set; }
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("deviceType", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the DeviceType /// Gets or sets the DeviceType
/// </summary> /// </summary>
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("deviceType", NullValueHandling = NullValueHandling.Ignore)]
public eEnvironmentalDeviceTypes DeviceType { get; private set; } public eEnvironmentalDeviceTypes DeviceType { get; private set; }
public EnvironmentalDeviceConfiguration(string key, eEnvironmentalDeviceTypes type) public EnvironmentalDeviceConfiguration(string key, eEnvironmentalDeviceTypes type)
@@ -1070,18 +1031,57 @@ namespace PepperDash.Essentials.RoomBridges
/// </summary> /// </summary>
public class ApiTouchPanelToken public class ApiTouchPanelToken
{ {
[JsonProperty("touchPanels", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the TouchPanels /// Gets or sets the TouchPanels
/// </summary> /// </summary>
[JsonProperty("touchPanels", NullValueHandling = NullValueHandling.Ignore)]
public List<JoinToken> TouchPanels { get; set; } = new List<JoinToken>(); public List<JoinToken> TouchPanels { get; set; } = new List<JoinToken>();
[JsonProperty("userAppUrl", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the UserAppUrl /// Gets or sets the UserAppUrl
/// </summary> /// </summary>
[JsonProperty("userAppUrl", NullValueHandling = NullValueHandling.Ignore)]
public string UserAppUrl { get; set; } = ""; 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.DeviceTypeInterfaces;
using PepperDash.Essentials.Core.UI; using PepperDash.Essentials.Core.UI;
using Feedback = PepperDash.Essentials.Core.Feedback; using Feedback = PepperDash.Essentials.Core.Feedback;
using IPAddress = System.Net.IPAddress;
namespace PepperDash.Essentials.Touchpanel namespace PepperDash.Essentials.Touchpanel
{ {
@@ -107,14 +106,11 @@ namespace PepperDash.Essentials.Touchpanel
/// </summary> /// </summary>
public DeviceInfo DeviceInfo => new DeviceInfo(); public DeviceInfo DeviceInfo => new DeviceInfo();
/// <summary>
/// Gets the list of connected IPs for this IpId
/// </summary>
public ReadOnlyCollection<ConnectedIpInformation> ConnectedIps => Panel.ConnectedIpList; 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> /// <summary>
@@ -194,27 +190,12 @@ namespace PepperDash.Essentials.Touchpanel
RegisterForExtenders(); RegisterForExtenders();
try var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
{ var csSubnetMask = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, csAdapterId);
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter); var csIpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
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.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask);
this.csIpAddress = IPAddress.Parse(csIpAddress); this.csIpAddress = System.Net.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);
}
} }
/// <summary> /// <summary>
@@ -245,7 +226,7 @@ namespace PepperDash.Essentials.Touchpanel
{ {
x70Panel.ExtenderApplicationControlReservedSigs.DeviceExtenderSigChange += (e, a) => 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(); UpdateZoomFeedbacks();
@@ -264,7 +245,7 @@ namespace PepperDash.Essentials.Touchpanel
x70Panel.ExtenderZoomRoomAppReservedSigs.DeviceExtenderSigChange += (e, a) => 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) if (a.Sig.Number == x70Panel.ExtenderZoomRoomAppReservedSigs.ZoomRoomIncomingCallFeedback.Number)
{ {
@@ -282,7 +263,7 @@ namespace PepperDash.Essentials.Touchpanel
DeviceInfo.MacAddress = x70Panel.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue; DeviceInfo.MacAddress = x70Panel.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
DeviceInfo.IpAddress = x70Panel.ExtenderEthernetReservedSigs.IpAddressFeedback.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; var handler = DeviceInfoChanged;
@@ -312,7 +293,7 @@ namespace PepperDash.Essentials.Touchpanel
{ {
x60withZoomApp.ExtenderApplicationControlReservedSigs.DeviceExtenderSigChange += (e, a) => 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) if (a.Sig.Number == x60withZoomApp.ExtenderApplicationControlReservedSigs.HideOpenApplicationFeedback.Number)
{ {
@@ -321,7 +302,7 @@ namespace PepperDash.Essentials.Touchpanel
}; };
x60withZoomApp.ExtenderZoomRoomAppReservedSigs.DeviceExtenderSigChange += (e, a) => 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) if (a.Sig.Number == x60withZoomApp.ExtenderZoomRoomAppReservedSigs.ZoomRoomIncomingCallFeedback.Number)
{ {
@@ -338,7 +319,7 @@ namespace PepperDash.Essentials.Touchpanel
DeviceInfo.MacAddress = x60withZoomApp.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue; DeviceInfo.MacAddress = x60withZoomApp.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
DeviceInfo.IpAddress = x60withZoomApp.ExtenderEthernetReservedSigs.IpAddressFeedback.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; var handler = DeviceInfoChanged;
@@ -400,7 +381,7 @@ namespace PepperDash.Essentials.Touchpanel
/// <param name="args">The signal event arguments containing the changed signal information.</param> /// <param name="args">The signal event arguments containing the changed signal information.</param>
protected override void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args) 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> /// <summary>
@@ -455,7 +436,7 @@ namespace PepperDash.Essentials.Touchpanel
var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, lanAdapterId); 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"); this.LogWarning("CS IP Address Subnet Mask or url is null, cannot determine correct IP for URL");
return url; return url;
@@ -466,7 +447,7 @@ namespace PepperDash.Essentials.Touchpanel
var ip = ConnectedIps.Any(ipInfo => 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); return csIpAddress.IsInSameSubnet(parsedIp, csSubnetMask);
} }
@@ -500,7 +481,7 @@ namespace PepperDash.Essentials.Touchpanel
if (mcList.Count == 0) if (mcList.Count == 0)
{ {
this.LogError("No Mobile Control controller found"); Debug.LogMessage(Serilog.Events.LogEventLevel.Information, this, $"No Mobile Control controller found");
return; return;
} }
@@ -512,7 +493,7 @@ namespace PepperDash.Essentials.Touchpanel
if (bridge == null) 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; return;
} }
@@ -521,7 +502,7 @@ namespace PepperDash.Essentials.Touchpanel
_bridge.UserCodeChanged += UpdateFeedbacks; _bridge.UserCodeChanged += UpdateFeedbacks;
_bridge.AppUrlChanged += (s, a) => _bridge.AppUrlChanged += (s, a) =>
{ {
this.LogInformation("AppURL changed: {appURL}", _bridge.AppUrl); this.LogInformation("AppURL changed");
SetAppUrl(_bridge.AppUrl); SetAppUrl(_bridge.AppUrl);
UpdateFeedbacks(s, a); UpdateFeedbacks(s, a);
}; };
@@ -557,7 +538,7 @@ namespace PepperDash.Essentials.Touchpanel
{ {
foreach (var feedback in ZoomFeedbacks) foreach (var feedback in ZoomFeedbacks)
{ {
this.LogDebug("Updating {feedbackKey}", feedback.Key); Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, this, $"Updating {feedback.Key}");
feedback.FireUpdate(); feedback.FireUpdate();
} }
} }
@@ -593,7 +574,7 @@ namespace PepperDash.Essentials.Touchpanel
if (Panel is TswX60WithZoomRoomAppReservedSigs) 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; return;
} }
} }
@@ -669,16 +650,7 @@ namespace PepperDash.Essentials.Touchpanel
handler(this, new DeviceInfoEventArgs(DeviceInfo)); handler(this, new DeviceInfoEventArgs(DeviceInfo));
} }
this.LogDebug("MAC: {macAddress} IP: {ipAddress}", DeviceInfo.MacAddress, DeviceInfo.IpAddress); Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, this, $"MAC: {DeviceInfo.MacAddress} IP: {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);
} }
} }
@@ -687,8 +659,6 @@ namespace PepperDash.Essentials.Touchpanel
/// </summary> /// </summary>
public class MobileControlTouchpanelControllerFactory : EssentialsPluginDeviceFactory<MobileControlTouchpanelController> public class MobileControlTouchpanelControllerFactory : EssentialsPluginDeviceFactory<MobileControlTouchpanelController>
{ {
private Dictionary<string, Func<uint, CrestronControlSystem, string, BasicTriListWithSmartObject>> factories;
/// <summary> /// <summary>
/// Initializes a new instance of the MobileControlTouchpanelControllerFactory class. /// Initializes a new instance of the MobileControlTouchpanelControllerFactory class.
/// Sets up supported device type names and minimum framework version requirements. /// 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" }; TypeNames = new List<string>() { "mccrestronapp", "mctsw550", "mctsw750", "mctsw1050", "mctsw560", "mctsw760", "mctsw1060", "mctsw570", "mctsw770", "mcts770", "mctsw1070", "mcts1070", "mcxpanel", "mcdge1000" };
MinimumEssentialsFrameworkVersion = "2.0.0"; 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> /// <summary>
@@ -741,10 +686,10 @@ namespace PepperDash.Essentials.Touchpanel
if (panel == null) 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); 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) private BasicTriListWithSmartObject GetPanelForType(string type, uint id, string projectName)
{ {
type = type.ToLower().Replace("mc", ""); type = type.ToLower().Replace("mc", "");
try 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 null;
} }
return buildCrestronHardwareDevice(id, Global.ControlSystem, projectName);
} }
catch (Exception e) catch (Exception e)
{ {
Debug.LogError("Cannot create TSW base class. Panel will not function: {message}", e.Message); Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
Debug.LogDebug(e, "Stack Trace: ");
return null; return null;
} }
} }

View File

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

View File

@@ -42,11 +42,10 @@ namespace PepperDash.Essentials.Touchpanel
/// </summary> /// </summary>
public class ThemeUpdateMessage : DeviceStateMessageBase public class ThemeUpdateMessage : DeviceStateMessageBase
{ {
[JsonProperty("theme")]
/// <summary> /// <summary>
/// Gets or sets the Theme /// Gets or sets the Theme
/// </summary> /// </summary>
[JsonProperty("theme")]
public string Theme { get; set; } 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> /// </summary>
public class UserCodeChangedContent public class UserCodeChangedContent
{ {
[JsonProperty("userCode")]
/// <summary> /// <summary>
/// Gets or sets the UserCode /// Gets or sets the UserCode
/// </summary> /// </summary>
[JsonProperty("userCode")]
public string UserCode { get; set; } public string UserCode { get; set; }
[JsonProperty("qrChecksum", NullValueHandling = NullValueHandling.Include)]
/// <summary> /// <summary>
/// Gets or sets the QrChecksum /// Gets or sets the QrChecksum
/// </summary> /// </summary>
[JsonProperty("qrChecksum", NullValueHandling = NullValueHandling.Include)]
public string QrChecksum { get; set; } 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 namespace PepperDash.Essentials
{ {
@@ -8,11 +8,10 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public class Volumes public class Volumes
{ {
[JsonProperty("master", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Master /// Gets or sets the Master
/// </summary> /// </summary>
[JsonProperty("master", NullValueHandling = NullValueHandling.Ignore)]
public Volume Master { get; set; } public Volume Master { get; set; }
[JsonProperty("auxFaders", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("auxFaders", NullValueHandling = NullValueHandling.Ignore)]
@@ -31,11 +30,10 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public class Volume public class Volume
{ {
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Key /// Gets or sets the Key
/// </summary> /// </summary>
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
public string Key { get; set; } public string Key { get; set; }
[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
@@ -44,11 +42,10 @@ namespace PepperDash.Essentials
[JsonProperty("muted", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("muted", NullValueHandling = NullValueHandling.Ignore)]
public bool? Muted { get; set; } public bool? Muted { get; set; }
[JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Label /// Gets or sets the Label
/// </summary> /// </summary>
[JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
public string Label { get; set; } public string Label { get; set; }
[JsonProperty("hasMute", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasMute", NullValueHandling = NullValueHandling.Ignore)]
@@ -61,11 +58,10 @@ namespace PepperDash.Essentials
public bool? PrivacyMuted { get; set; } public bool? PrivacyMuted { get; set; }
[JsonProperty("muteIcon", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the MuteIcon /// Gets or sets the MuteIcon
/// </summary> /// </summary>
[JsonProperty("muteIcon", NullValueHandling = NullValueHandling.Ignore)]
public string MuteIcon { get; set; } public string MuteIcon { get; set; }
public Volume(string key, int level, bool muted, string label, bool hasMute, string muteIcon) 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 Crestron.SimplSharp.WebScripting;
using System.Linq;
using Crestron.SimplSharp.WebScripting;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Core.Web.RequestHandlers; using PepperDash.Core.Web.RequestHandlers;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.WebApiHandlers namespace PepperDash.Essentials.WebApiHandlers
{ {
@@ -51,18 +51,16 @@ namespace PepperDash.Essentials.WebApiHandlers
/// </summary> /// </summary>
public class ActionPath public class ActionPath
{ {
[JsonProperty("messengerKey")]
/// <summary> /// <summary>
/// Gets or sets the MessengerKey /// Gets or sets the MessengerKey
/// </summary> /// </summary>
[JsonProperty("messengerKey")]
public string MessengerKey { get; set; } public string MessengerKey { get; set; }
[JsonProperty("path")]
/// <summary> /// <summary>
/// Gets or sets the Path /// Gets or sets the Path
/// </summary> /// </summary>
[JsonProperty("path")]
public string Path { get; set; } public string Path { get; set; }
} }
} }

View File

@@ -148,25 +148,22 @@ namespace PepperDash.Essentials.WebApiHandlers
/// </summary> /// </summary>
public class ClientRequest public class ClientRequest
{ {
[JsonProperty("roomKey", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the RoomKey /// Gets or sets the RoomKey
/// </summary> /// </summary>
[JsonProperty("roomKey", NullValueHandling = NullValueHandling.Ignore)]
public string RoomKey { get; set; } public string RoomKey { get; set; }
[JsonProperty("grantCode", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the GrantCode /// Gets or sets the GrantCode
/// </summary> /// </summary>
[JsonProperty("grantCode", NullValueHandling = NullValueHandling.Ignore)]
public string GrantCode { get; set; } public string GrantCode { get; set; }
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Token /// Gets or sets the Token
/// </summary> /// </summary>
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
public string Token { get; set; } public string Token { get; set; }
} }
@@ -175,25 +172,22 @@ namespace PepperDash.Essentials.WebApiHandlers
/// </summary> /// </summary>
public class ClientResponse public class ClientResponse
{ {
[JsonProperty("error", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Error /// Gets or sets the Error
/// </summary> /// </summary>
[JsonProperty("error", NullValueHandling = NullValueHandling.Ignore)]
public string Error { get; set; } public string Error { get; set; }
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Token /// Gets or sets the Token
/// </summary> /// </summary>
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
public string Token { get; set; } public string Token { get; set; }
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
/// <summary> /// <summary>
/// Gets or sets the Path /// Gets or sets the Path
/// </summary> /// </summary>
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
public string Path { get; set; } 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.IO;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.WebScripting; using Crestron.SimplSharp.WebScripting;
@@ -37,10 +35,6 @@ namespace PepperDash.Essentials.WebSocketServer
private readonly string appConfigFileName = "_config.local.json"; private readonly string appConfigFileName = "_config.local.json";
private readonly string appConfigCsFileName = "_config.cs.json"; private readonly string appConfigCsFileName = "_config.cs.json";
private const string certificateName = "selfCres";
private const string certificatePassword = "cres12345";
/// <summary> /// <summary>
/// Where the key is the join token and the value is the room key /// Where the key is the join token and the value is the room key
/// </summary> /// </summary>
@@ -161,7 +155,7 @@ namespace PepperDash.Essentials.WebSocketServer
{ {
try 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 csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
var csIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId); 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) 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) 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) catch (Exception ex)
{ {
this.LogError("Error automatically forwarding port to CS LAN: {message}", ex.Message); Debug.LogMessage(ex, "Error automatically forwarding port to CS LAN");
this.LogDebug(ex, "Stack Trace");
} }
} }
@@ -197,7 +190,7 @@ namespace PepperDash.Essentials.WebSocketServer
{ {
if (parent.Config.DirectServer.AutomaticallyForwardPortToCSLAN == false) 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; _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; CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
_server.Start(); _server.Start();
if (_server.IsListening) 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; CrestronEnvironment.ProgramStatusEventHandler += OnProgramStop;
@@ -321,17 +278,10 @@ namespace PepperDash.Essentials.WebSocketServer
} }
catch (Exception ex) catch (Exception ex)
{ {
this.LogError("Exception initializing direct server: {message}", ex.Message); Debug.LogMessage(ex, "Exception intializing websocket server", this);
this.LogDebug(ex, "Stack Trace");
} }
} }
public void SetWebsocketLogLevel(LogLevel level)
{
CrestronConsole.ConsoleCommandResponse($"Setting direct server debug level to {level}", level.ToString());
_server.Log.Level = level;
}
private void AddClientsForTouchpanels() private void AddClientsForTouchpanels()
{ {
var touchpanels = DeviceManager.AllDevices var touchpanels = DeviceManager.AllDevices
@@ -397,6 +347,22 @@ namespace PepperDash.Essentials.WebSocketServer
string ip = processorIp; 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) if (_parent.Config.DirectServer.CSLanUiDeviceKeys != null && _parent.Config.DirectServer.CSLanUiDeviceKeys.Any(k => k.Equals(touchpanel.Touchpanel.Key, StringComparison.InvariantCultureIgnoreCase)) && csIpAddress != null)
{ {
ip = csIpAddress.ToString(); ip = csIpAddress.ToString();
@@ -511,8 +477,7 @@ namespace PepperDash.Essentials.WebSocketServer
} }
catch (Exception ex) catch (Exception ex)
{ {
this.LogError("Error getting application configuration: {message}", ex.Message); this.LogError(ex, "Error getting application configuration");
this.LogDebug(ex, "Stack Trace");
return null; return null;
} }
@@ -548,14 +513,15 @@ namespace PepperDash.Essentials.WebSocketServer
{ {
if (token.Value == null) if (token.Value == null)
{ {
this.LogWarning("Token value is null"); Debug.LogMessage(LogEventLevel.Warning, "Token value is null", this);
continue; 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) if (UiClients == null)
{ {
Debug.LogMessage(LogEventLevel.Warning, "UiClients is null", this);
UiClients = new Dictionary<string, UiClientContext>(); UiClients = new Dictionary<string, UiClientContext>();
} }
@@ -565,7 +531,7 @@ namespace PepperDash.Essentials.WebSocketServer
if (UiClients.Count > 0) 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) foreach (var client in UiClients)
{ {
@@ -575,28 +541,36 @@ namespace PepperDash.Essentials.WebSocketServer
_server.AddWebSocketService(path, () => _server.AddWebSocketService(path, () =>
{ {
var c = new UiClient($"uiclient-{key}-{roomKey}"); var c = new UiClient();
this.LogDebug("Constructing UiClient with id: {key}", key); Debug.LogMessage(LogEventLevel.Debug, "Constructing UiClient with id: {key}", this, key);
c.Controller = _parent; c.Controller = _parent;
c.RoomKey = roomKey; c.RoomKey = roomKey;
UiClients[key].SetClient(c); UiClients[key].SetClient(c);
return 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 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) catch (Exception ex)
{ {
this.LogError("Exception retrieving secret: {message}", ex.Message); Debug.LogMessage(ex, "Exception retrieving secret", this);
this.LogDebug(ex, "Stack Trace");
} }
} }
@@ -609,7 +583,7 @@ namespace PepperDash.Essentials.WebSocketServer
{ {
if (_secret == null) if (_secret == null)
{ {
this.LogError("Secret is null"); Debug.LogMessage(LogEventLevel.Error, "Secret is null", this);
_secret = new ServerTokenSecrets(string.Empty); _secret = new ServerTokenSecrets(string.Empty);
} }
@@ -627,8 +601,7 @@ namespace PepperDash.Essentials.WebSocketServer
} }
catch (Exception ex) catch (Exception ex)
{ {
this.LogError("Exception updating secret: {message}", ex.Message); Debug.LogMessage(ex, "Exception updating secret", this);
this.LogDebug(ex, "Stack Trace");
} }
} }
@@ -731,18 +704,18 @@ namespace PepperDash.Essentials.WebSocketServer
_server.AddWebSocketService(path, () => _server.AddWebSocketService(path, () =>
{ {
var c = new UiClient($"uiclient-{key}-{bridge.RoomKey}"); var c = new UiClient();
this.LogVerbose("Constructing UiClient with id: {key}", key); Debug.LogMessage(LogEventLevel.Verbose, "Constructing UiClient with id: {0}", this, key);
c.Controller = _parent; c.Controller = _parent;
c.RoomKey = bridge.RoomKey; c.RoomKey = bridge.RoomKey;
UiClients[key].SetClient(c); UiClients[key].SetClient(c);
return c; return c;
}); });
this.LogInformation("Added new WebSocket UiClient service at path: {path}", path); Debug.LogMessage(LogEventLevel.Information, "Added new WebSocket UiClient service at path: {path}", this, path);
this.LogInformation("Token: {@token}", token); 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(); UpdateSecret();
@@ -756,7 +729,7 @@ namespace PepperDash.Essentials.WebSocketServer
{ {
if (s == "?" || string.IsNullOrEmpty(s)) 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; return;
} }
@@ -910,8 +883,7 @@ namespace PepperDash.Essentials.WebSocketServer
} }
catch (Exception ex) catch (Exception ex)
{ {
this.LogError("Exception in OnGet handler: {message}", ex.Message); Debug.LogMessage(ex, "Caught an exception in the OnGet handler", this);
this.LogDebug(ex, "Stack Trace");
} }
} }
@@ -1000,20 +972,6 @@ namespace PepperDash.Essentials.WebSocketServer
res.StatusCode = 200; res.StatusCode = 200;
res.ContentType = "application/json"; 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 // Construct the response object
JoinResponse jRes = new JoinResponse JoinResponse jRes = new JoinResponse
{ {
@@ -1027,8 +985,7 @@ namespace PepperDash.Essentials.WebSocketServer
UserAppUrl = string.Format("http://{0}:{1}/mc/app", UserAppUrl = string.Format("http://{0}:{1}/mc/app",
CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0), CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0),
Port), Port),
EnableDebug = false, EnableDebug = false
DeviceInterfaceSupport = deviceInterfaces
}; };
// Serialize to JSON and convert to Byte[] // Serialize to JSON and convert to Byte[]
@@ -1214,7 +1171,7 @@ namespace PepperDash.Essentials.WebSocketServer
} }
else else
{ {
this.LogWarning("File not found: {filePath}", filePath); this.LogVerbose("File not found: {filePath}", filePath);
res.StatusCode = (int)HttpStatusCode.NotFound; res.StatusCode = (int)HttpStatusCode.NotFound;
res.Close(); res.Close();
return; 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; }
}
} }

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