mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-02 06:14:52 +00:00
Compare commits
7 Commits
v2.1.0-fea
...
v2.1.0-fea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0a68f38f5 | ||
|
|
46887579e4 | ||
|
|
b095d926d2 | ||
|
|
7cebf861cc | ||
|
|
2e0b003118 | ||
|
|
bada7e3a25 | ||
|
|
67a7422cd0 |
@@ -9,14 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PepperDash.Essentials", "sr
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PepperDash.Essentials.Core", "src\PepperDash.Essentials.Core\PepperDash.Essentials.Core.csproj", "{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Control", "Mobile Control", "{B24989D7-32B5-48D5-9AE1-5F3B17D25206}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDash.Essentials.MobileControl", "src\PepperDash.Essentials.MobileControl\PepperDash.Essentials.MobileControl.csproj", "{F6D362DE-2256-44B1-927A-8CE4705D839A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDash.Essentials.MobileControl.Messengers", "src\PepperDash.Essentials.MobileControl.Messengers\PepperDash.Essentials.MobileControl.Messengers.csproj", "{B438694F-8FF7-464A-9EC8-10427374471F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Essentials", "Essentials", "{AD98B742-8D85-481C-A69D-D8D8ABED39EA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug 4.7.2|Any CPU = Debug 4.7.2|Any CPU
|
||||
@@ -42,29 +34,10 @@ Global
|
||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Debug 4.7.2|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Debug 4.7.2|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Debug 4.7.2|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Debug 4.7.2|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{53E204B7-97DD-441D-A96C-721DF014DF82} = {AD98B742-8D85-481C-A69D-D8D8ABED39EA}
|
||||
{CB3B11BA-625C-4D35-B663-FDC5BE9A230E} = {AD98B742-8D85-481C-A69D-D8D8ABED39EA}
|
||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B} = {AD98B742-8D85-481C-A69D-D8D8ABED39EA}
|
||||
{F6D362DE-2256-44B1-927A-8CE4705D839A} = {B24989D7-32B5-48D5-9AE1-5F3B17D25206}
|
||||
{B438694F-8FF7-464A-9EC8-10427374471F} = {B24989D7-32B5-48D5-9AE1-5F3B17D25206}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {6907A4BF-7201-47CF-AAB1-3597F3B8E1C3}
|
||||
EndGlobalSection
|
||||
|
||||
@@ -60,4 +60,4 @@ For detailed documentation, see the [Wiki](https://github.com/PepperDash/Essenti
|
||||
|
||||
## How-To (Getting Started)
|
||||
|
||||
See [Getting Started](https://github.com/PepperDash/Essentials/wiki/Get-started#how-to-get-started)
|
||||
See [Getting Started](https://github.com/PepperDash/Essentials/wiki/Get-started#how-to-get-started)
|
||||
@@ -0,0 +1,85 @@
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper class for CEN-IO-COM-Xxx expander module
|
||||
/// </summary>
|
||||
[Description("Wrapper class for the CEN-IO-COM-102 & CEN-IO-COM-202 expander module")]
|
||||
public class CenIoComController : CrestronGenericBaseDevice, IComPorts
|
||||
{
|
||||
private readonly CenIoCom _cenIoCom;
|
||||
|
||||
public CenIoComController(string key, string name, CenIoCom cenIo)
|
||||
:base(key, name, cenIo)
|
||||
{
|
||||
_cenIoCom = cenIo;
|
||||
}
|
||||
|
||||
#region Implementation of IComPorts
|
||||
|
||||
public CrestronCollection<ComPort> ComPorts
|
||||
{
|
||||
get { return _cenIoCom.ComPorts; }
|
||||
}
|
||||
|
||||
public int NumberOfComPorts
|
||||
{
|
||||
get { return _cenIoCom.NumberOfComPorts; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
public class CenIoCom102ControllerFactory : EssentialsDeviceFactory<CenIoComController>
|
||||
{
|
||||
private const string CenIoCom102Type = "ceniocom102";
|
||||
private const string CenIoCom202Type = "ceniocom202";
|
||||
|
||||
public CenIoCom102ControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string> { CenIoCom102Type, CenIoCom202Type };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new CEN-IO-COM-Xxx Device");
|
||||
|
||||
var control = CommFactory.GetControlPropertiesConfig(dc);
|
||||
if (control == null)
|
||||
{
|
||||
Debug.Console(1, "Factory failed to create a new CEN-IO-COM-Xxx Device, control properties not found");
|
||||
return null;
|
||||
}
|
||||
|
||||
var ipid = control.IpIdInt;
|
||||
if (ipid < 2)
|
||||
{
|
||||
Debug.Console(1, "Factory failed to create a new CEN-IO-COM-Xxx Device, invalid IP-ID found");
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (dc.Type)
|
||||
{
|
||||
case CenIoCom102Type:
|
||||
{
|
||||
return new CenIoComController(dc.Key, dc.Name, new CenIoCom102(ipid, Global.ControlSystem));
|
||||
}
|
||||
case CenIoCom202Type:
|
||||
{
|
||||
return new CenIoComController(dc.Key, dc.Name, new CenIoCom202(ipid, Global.ControlSystem));
|
||||
}
|
||||
default:
|
||||
{
|
||||
Debug.Console(1, "Factory failed to create a new CEN-IO-COM-Xxx Device, invalid type '{0}'", dc.Type);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash_Essentials_DM.Chassis
|
||||
{
|
||||
public class HdPsXxxAnalogAuxMixerController : IKeyed,
|
||||
IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback
|
||||
{
|
||||
public string Key { get; private set; }
|
||||
|
||||
private readonly HdPsXxxAnalogAuxMixer _mixer;
|
||||
|
||||
public HdPsXxxAnalogAuxMixerController(string parent, uint mixer, HdPsXxx chassis)
|
||||
{
|
||||
Key = string.Format("{0}-analogMixer{1}", parent, mixer);
|
||||
|
||||
_mixer = chassis.AnalogAuxiliaryMixer[mixer];
|
||||
|
||||
_mixer.AuxMixerPropertyChange += OnAuxMixerPropertyChange;
|
||||
_mixer.AuxiliaryMuteControl.MuteAndVolumeControlPropertyChange += OnMuteAndVolumeControlPropertyChange;
|
||||
|
||||
VolumeLevelFeedback = new IntFeedback(() => VolumeLevel);
|
||||
MuteFeedback = new BoolFeedback(() => IsMuted);
|
||||
}
|
||||
|
||||
#region Volume
|
||||
|
||||
private void OnAuxMixerPropertyChange(object sender, GenericEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "OnAuxMixerPropertyChange: {0} > Index-{1}, EventId-{2}", sender.ToString(), args.Index, args.EventId);
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case MuteAndVolumeContorlEventIds.VolumeFeedbackEventId:
|
||||
{
|
||||
VolumeLevel = _mixer.VolumeFeedback.ShortValue;
|
||||
break;
|
||||
}
|
||||
case MuteAndVolumeContorlEventIds.MuteOnEventId:
|
||||
case MuteAndVolumeContorlEventIds.MuteOffEventId:
|
||||
{
|
||||
IsMuted = _mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Debug.Console(1, this, "OnAuxMixerPropertyChange: {0} > Index-{1}, EventId-{2} - unhandled eventId", sender.ToString(), args.Index, args.EventId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const ushort CrestronLevelMin = 0;
|
||||
private const ushort CrestronLevelMax = 65535;
|
||||
|
||||
private const int DeviceLevelMin = -800;
|
||||
private const int DeviceLevelMax = 200;
|
||||
|
||||
private const int RampTime = 5000;
|
||||
|
||||
private int _volumeLevel;
|
||||
|
||||
public int VolumeLevel
|
||||
{
|
||||
get { return _volumeLevel; }
|
||||
private set
|
||||
{
|
||||
var level = value;
|
||||
|
||||
_volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin);
|
||||
|
||||
Debug.Console(1, this, "VolumeFeedback: level-'{0}', scaled-'{1}'", level, _volumeLevel);
|
||||
|
||||
VolumeLevelFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public IntFeedback VolumeLevelFeedback { get; private set; }
|
||||
|
||||
public void SetVolume(ushort level)
|
||||
{
|
||||
var levelScaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin);
|
||||
|
||||
Debug.Console(1, this, "SetVolume: level-'{0}', levelScaled-'{1}'", level, levelScaled);
|
||||
|
||||
_mixer.Volume.ShortValue = (short)levelScaled;
|
||||
}
|
||||
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
if (pressRelease)
|
||||
{
|
||||
_mixer.Volume.CreateSignedRamp(DeviceLevelMax, RampTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mixer.Volume.StopRamp();
|
||||
}
|
||||
}
|
||||
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
if (pressRelease)
|
||||
{
|
||||
_mixer.Volume.CreateSignedRamp(DeviceLevelMin, RampTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mixer.Volume.StopRamp();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
#region Mute
|
||||
|
||||
private void OnMuteAndVolumeControlPropertyChange(MuteControl device, GenericEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "OnMuteAndVolumeControlPropertyChange: {0} > Index-{1}, EventId-{2}", device.ToString(), args.Index, args.EventId);
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case MuteAndVolumeContorlEventIds.VolumeFeedbackEventId:
|
||||
{
|
||||
VolumeLevel = _mixer.VolumeFeedback.ShortValue;
|
||||
break;
|
||||
}
|
||||
case MuteAndVolumeContorlEventIds.MuteOnEventId:
|
||||
case MuteAndVolumeContorlEventIds.MuteOffEventId:
|
||||
{
|
||||
IsMuted = _mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Debug.Console(1, this, "OnMuteAndVolumeControlPropertyChange: {0} > Index-{1}, EventId-{2} - unhandled eventId", device.ToString(), args.Index, args.EventId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isMuted;
|
||||
|
||||
public bool IsMuted
|
||||
{
|
||||
get { return _isMuted; }
|
||||
set
|
||||
{
|
||||
_isMuted = value;
|
||||
|
||||
Debug.Console(1, this, "IsMuted: _isMuted-'{0}'", _isMuted);
|
||||
|
||||
MuteFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public BoolFeedback MuteFeedback { get; private set; }
|
||||
|
||||
public void MuteOn()
|
||||
{
|
||||
_mixer.AuxiliaryMuteControl.MuteOn();
|
||||
}
|
||||
|
||||
public void MuteOff()
|
||||
{
|
||||
_mixer.AuxiliaryMuteControl.MuteOff();
|
||||
}
|
||||
|
||||
public void MuteToggle()
|
||||
{
|
||||
if (IsMuted)
|
||||
MuteOff();
|
||||
else
|
||||
MuteOn();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash_Essentials_DM.Chassis
|
||||
{
|
||||
public class HdPsXxxOutputAudioController : IKeyed,
|
||||
IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback
|
||||
{
|
||||
public string Key { get; private set; }
|
||||
|
||||
private readonly HdPsXxxHdmiDmLiteOutputMixer _mixer; // volume/volumeFeedback
|
||||
private readonly HdPsXxxOutputPort _port; // mute/muteFeedback
|
||||
|
||||
public HdPsXxxOutputAudioController(string parent, uint output, HdPsXxx chassis)
|
||||
{
|
||||
Key = string.Format("{0}-audioOut{1}", parent, output);
|
||||
|
||||
_port = chassis.HdmiDmLiteOutputs[output].OutputPort;
|
||||
_mixer = chassis.HdmiDmLiteOutputs[output].Mixer;
|
||||
|
||||
chassis.DMOutputChange += ChassisOnDmOutputChange;
|
||||
|
||||
VolumeLevelFeedback = new IntFeedback(() => VolumeLevel);
|
||||
MuteFeedback = new BoolFeedback(() => IsMuted);
|
||||
}
|
||||
|
||||
private void ChassisOnDmOutputChange(Switch device, DMOutputEventArgs args)
|
||||
{
|
||||
switch (args.EventId)
|
||||
{
|
||||
case (DMOutputEventIds.VolumeEventId):
|
||||
{
|
||||
Debug.Console(2, this, "HdPsXxxOutputAudioController: {0} > Index-{1}, Number-{3}, EventId-{2} - AudioMute/UnmuteEventId",
|
||||
device.ToString(), args.Index, args.EventId, args.Number);
|
||||
|
||||
VolumeLevel = _mixer.VolumeFeedback.ShortValue;
|
||||
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.MuteOnEventId:
|
||||
case DMOutputEventIds.MuteOffEventId:
|
||||
{
|
||||
Debug.Console(2, this, "HdPsXxxOutputAudioController: {0} > Index-{1}, Number-{3}, EventId-{2} - MuteOnEventId/MuteOffEventId",
|
||||
device.ToString(), args.Index, args.EventId, args.Number);
|
||||
|
||||
IsMuted = _port.MuteOnFeedback.BoolValue;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Debug.Console(1, this, "HdPsXxxOutputAudioController: {0} > Index-{1}, Number-{3}, EventId-{2} - unhandled eventId",
|
||||
device.ToString(), args.Index, args.EventId, args.Number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Volume
|
||||
|
||||
private const ushort CrestronLevelMin = 0;
|
||||
private const ushort CrestronLevelMax = 65535;
|
||||
|
||||
private const int DeviceLevelMin = -800;
|
||||
private const int DeviceLevelMax = 200;
|
||||
|
||||
private const int RampTime = 5000;
|
||||
|
||||
private int _volumeLevel;
|
||||
|
||||
public int VolumeLevel
|
||||
{
|
||||
get { return _volumeLevel; }
|
||||
private set
|
||||
{
|
||||
var level = value;
|
||||
|
||||
_volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin);
|
||||
|
||||
Debug.Console(2, this, "VolumeFeedback: level-'{0}', scaled-'{1}'", level, _volumeLevel);
|
||||
|
||||
VolumeLevelFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public IntFeedback VolumeLevelFeedback { get; private set; }
|
||||
|
||||
public void SetVolume(ushort level)
|
||||
{
|
||||
var levelScaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin);
|
||||
|
||||
Debug.Console(1, this, "SetVolume: level-'{0}', levelScaled-'{1}'", level, levelScaled);
|
||||
|
||||
_mixer.Volume.ShortValue = (short)levelScaled;
|
||||
}
|
||||
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
if (pressRelease)
|
||||
{
|
||||
_mixer.Volume.CreateSignedRamp(DeviceLevelMax, RampTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mixer.Volume.StopRamp();
|
||||
}
|
||||
}
|
||||
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
if (pressRelease)
|
||||
{
|
||||
_mixer.Volume.CreateSignedRamp(DeviceLevelMin, RampTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mixer.Volume.StopRamp();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
#region Mute
|
||||
|
||||
private bool _isMuted;
|
||||
|
||||
public bool IsMuted
|
||||
{
|
||||
get { return _isMuted; }
|
||||
set
|
||||
{
|
||||
_isMuted = value;
|
||||
|
||||
Debug.Console(1, this, "IsMuted: _isMuted-'{0}'", _isMuted);
|
||||
|
||||
MuteFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public BoolFeedback MuteFeedback { get; private set; }
|
||||
|
||||
public void MuteOn()
|
||||
{
|
||||
_port.MuteOn();
|
||||
}
|
||||
|
||||
public void MuteOff()
|
||||
{
|
||||
_port.MuteOff();
|
||||
}
|
||||
|
||||
public void MuteToggle()
|
||||
{
|
||||
if (IsMuted)
|
||||
MuteOff();
|
||||
else
|
||||
MuteOn();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,10 @@
|
||||
<PropertyGroup>
|
||||
<Version>2.0.0-local</Version>
|
||||
<InformationalVersion>$(Version)</InformationalVersion>
|
||||
<Authors>PepperDash Technology</Authors>
|
||||
<Company>PepperDash Technology</Company>
|
||||
<Authors>PepperDash Technologies</Authors>
|
||||
<Company>PepperDash Technologies</Company>
|
||||
<Product>PepperDash Essentials</Product>
|
||||
<Copyright>Copyright © 2025</Copyright>
|
||||
<Copyright>Copyright © 2023</Copyright>
|
||||
<RepositoryUrl>https://github.com/PepperDash/Essentials</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>Crestron; 4series</PackageTags>
|
||||
|
||||
@@ -7,19 +7,17 @@ namespace PepperDash.Essentials.Core
|
||||
[Obsolete("Please use the builtin HttpClient class instead: https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines")]
|
||||
public class GenericHttpClient : Device, IBasicCommunication
|
||||
{
|
||||
private readonly HttpClient Client;
|
||||
public HttpClient Client;
|
||||
public event EventHandler<GenericHttpClientEventArgs> ResponseRecived;
|
||||
|
||||
public GenericHttpClient(string key, string name, string hostname)
|
||||
: base(key, name)
|
||||
{
|
||||
Client = new HttpClient
|
||||
{
|
||||
HostName = hostname
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
Client = new HttpClient();
|
||||
Client.HostName = hostname;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -56,8 +54,9 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
if (responseReceived.ContentString.Length > 0)
|
||||
{
|
||||
ResponseRecived?.Invoke(this, new GenericHttpClientEventArgs(responseReceived.ContentString, (request as HttpClientRequest).Url.ToString(), error));
|
||||
}
|
||||
if (ResponseRecived != null)
|
||||
ResponseRecived(this, new GenericHttpClientEventArgs(responseReceived.ContentString, (request as HttpClientRequest).Url.ToString(), error));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IDisplay: IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IKeyName
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasWebView
|
||||
{
|
||||
void ShowWebView(string url, string mode, string title, string target);
|
||||
void HideWebView();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,12 @@
|
||||
using PepperDash.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
@@ -8,6 +16,22 @@ namespace PepperDash.Essentials.Core
|
||||
BoolFeedback IsOnline { get; }
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// ** WANT THIS AND ALL ITS FRIENDS TO GO AWAY **
|
||||
///// Defines a class that has a list of CueAction objects, typically
|
||||
///// for linking functions to user interfaces or API calls
|
||||
///// </summary>
|
||||
//public interface IHasCueActionList
|
||||
//{
|
||||
// List<CueActionPair> CueActionList { get; }
|
||||
//}
|
||||
|
||||
|
||||
//public interface IHasComPortsHardware
|
||||
//{
|
||||
// IComPorts ComPortsDevice { get; }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a device that can have a video sync providing device attached to it
|
||||
/// </summary>
|
||||
|
||||
81
src/PepperDash.Essentials.Core/Devices/PC/Laptop.cs
Normal file
81
src/PepperDash.Essentials.Core/Devices/PC/Laptop.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices
|
||||
{
|
||||
|
||||
[Obsolete("Please use PepperDash.Essentials.Devices.Common, this will be removed in 2.1")]
|
||||
public class Laptop : EssentialsDevice, IHasFeedback, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
|
||||
{
|
||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
|
||||
public string IconName { get; set; }
|
||||
public BoolFeedback HasPowerOnFeedback { get; private set; }
|
||||
|
||||
public RoutingOutputPort AnyVideoOut { get; private set; }
|
||||
|
||||
#region IRoutingOutputs Members
|
||||
|
||||
/// <summary>
|
||||
/// Options: hdmi
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
public Laptop(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
IconName = "Laptop";
|
||||
HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback",
|
||||
() => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus);
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
OutputPorts.Add(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.None, 0, this));
|
||||
}
|
||||
|
||||
#region IHasFeedback Members
|
||||
|
||||
/// <summary>
|
||||
/// Passes through the VideoStatuses list
|
||||
/// </summary>
|
||||
public FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
var newList = new FeedbackCollection<Feedback>();
|
||||
newList.AddRange(this.GetVideoStatuses().ToList());
|
||||
return newList;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IUsageTracking Members
|
||||
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
[Obsolete("Please use PepperDash.Essentials.Devices.Common, this will be removed in 2.1")]
|
||||
public class LaptopFactory : EssentialsDeviceFactory<Laptop>
|
||||
{
|
||||
public LaptopFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "deprecated" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Laptop Device");
|
||||
return new Core.Devices.Laptop(dc.Key, dc.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
229
src/PepperDash.Essentials.Core/Display/BasicIrDisplay.cs
Normal file
229
src/PepperDash.Essentials.Core/Display/BasicIrDisplay.cs
Normal file
@@ -0,0 +1,229 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
[Obsolete("Please use PepperDash.Essentials.Device.Common, this will be removed in 2.1")]
|
||||
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced
|
||||
{
|
||||
public IrOutputPortController IrPort { get; private set; }
|
||||
public ushort IrPulseTime { get; set; }
|
||||
|
||||
protected Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
get { return () => _PowerIsOn; }
|
||||
}
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||
{
|
||||
get { return () => _IsCoolingDown; }
|
||||
}
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc
|
||||
{
|
||||
get { return () => _IsWarmingUp; }
|
||||
}
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
|
||||
public BasicIrDisplay(string key, string name, IROutputPort port, string irDriverFilepath)
|
||||
: base(key, name)
|
||||
{
|
||||
IrPort = new IrOutputPortController(key + "-ir", port, irDriverFilepath);
|
||||
DeviceManager.AddDevice(IrPort);
|
||||
|
||||
IsWarmingUpFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Verbose, this, "Warming up={0}", _IsWarmingUp);
|
||||
IsCoolingDownFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Verbose, this, "Cooling down={0}", _IsCoolingDown);
|
||||
|
||||
InputPorts.AddRange(new RoutingPortCollection<RoutingInputPort>
|
||||
{
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi2), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi3), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi4), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Component1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Video1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Antenna), this, false),
|
||||
});
|
||||
}
|
||||
|
||||
public void Hdmi1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_1, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Hdmi2()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_2, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Hdmi3()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_3, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Hdmi4()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_4, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Component1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_COMPONENT_1, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Video1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_VIDEO_1, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Antenna()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_ANTENNA, IrPulseTime);
|
||||
}
|
||||
|
||||
#region IPower Members
|
||||
|
||||
public override void PowerOn()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
|
||||
_PowerIsOn = true;
|
||||
}
|
||||
|
||||
public override void PowerOff()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
|
||||
}
|
||||
|
||||
public override void PowerToggle()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IBasicVolumeControls Members
|
||||
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_PLUS, pressRelease);
|
||||
}
|
||||
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_MINUS, pressRelease);
|
||||
}
|
||||
|
||||
public void MuteToggle()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_MUTE, 200);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
void StartWarmingTimer()
|
||||
{
|
||||
_IsWarmingUp = true;
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
new CTimer(o => {
|
||||
_IsWarmingUp = false;
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
void StartCoolingTimer()
|
||||
{
|
||||
_IsCoolingDown = true;
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
new CTimer(o =>
|
||||
{
|
||||
_IsCoolingDown = false;
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
}, 7000);
|
||||
}
|
||||
|
||||
#region IRoutingSink Members
|
||||
|
||||
/// <summary>
|
||||
/// Typically called by the discovery routing algorithm.
|
||||
/// </summary>
|
||||
/// <param name="inputSelector">A delegate containing the input selector method to call</param>
|
||||
public override void ExecuteSwitch(object inputSelector)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Switching to input '{0}'", (inputSelector as Action).ToString());
|
||||
|
||||
Action finishSwitch = () =>
|
||||
{
|
||||
var action = inputSelector as Action;
|
||||
if (action != null)
|
||||
action();
|
||||
};
|
||||
|
||||
if (!_PowerIsOn)
|
||||
{
|
||||
PowerOn();
|
||||
EventHandler<FeedbackEventArgs> oneTimer = null;
|
||||
oneTimer = (o, a) =>
|
||||
{
|
||||
if (IsWarmingUpFeedback.BoolValue) return; // Only catch done warming
|
||||
IsWarmingUpFeedback.OutputChange -= oneTimer;
|
||||
finishSwitch();
|
||||
};
|
||||
IsWarmingUpFeedback.OutputChange += oneTimer;
|
||||
}
|
||||
else // Do it!
|
||||
finishSwitch();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Please use PepperDash.Essentials.Device.Common, this will be removed in 2.1")]
|
||||
public class BasicIrDisplayFactory : EssentialsDeviceFactory<BasicIrDisplay>
|
||||
{
|
||||
public BasicIrDisplayFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "basicirdisplay" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BasicIrDisplay Device");
|
||||
var ir = IRPortHelper.GetIrPort(dc.Properties);
|
||||
if (ir != null)
|
||||
{
|
||||
var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName);
|
||||
display.IrPulseTime = 200; // Set default pulse time for IR commands.
|
||||
return display;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
320
src/PepperDash.Essentials.Core/Display/DisplayBase.cs
Normal file
320
src/PepperDash.Essentials.Core/Display/DisplayBase.cs
Normal file
@@ -0,0 +1,320 @@
|
||||
|
||||
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
[Obsolete("Please use PepperDash.Essentials.Devices.Common, this will be removed in 2.1")]
|
||||
public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking
|
||||
{
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
public event InputChangedEventHandler InputChanged;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
public uint WarmupTime { get; set; }
|
||||
public uint CooldownTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
|
||||
/// by concrete sub-classes
|
||||
/// </summary>
|
||||
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
|
||||
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
|
||||
|
||||
|
||||
protected CTimer WarmupTimer;
|
||||
protected CTimer CooldownTimer;
|
||||
|
||||
#region IRoutingInputs Members
|
||||
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
protected DisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
||||
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
|
||||
}
|
||||
|
||||
public abstract void PowerOn();
|
||||
public abstract void PowerOff();
|
||||
public abstract void PowerToggle();
|
||||
|
||||
public virtual FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FeedbackCollection<Feedback>
|
||||
{
|
||||
IsCoolingDownFeedback,
|
||||
IsWarmingUpFeedback
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public RoutingInputPort CurrentInputPort => throw new NotImplementedException();
|
||||
|
||||
public abstract void ExecuteSwitch(object selector);
|
||||
|
||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||
EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new DisplayControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DisplayControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information,this,"Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
LinkDisplayToApi(displayDevice, trilist, joinMap);
|
||||
}
|
||||
|
||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, DisplayControllerJoinMap joinMap)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.LogMessage(LogEventLevel.Information, "Linking to Display: {0}", displayDevice.Name);
|
||||
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
|
||||
|
||||
var commMonitor = displayDevice as ICommunicationMonitor;
|
||||
if (commMonitor != null)
|
||||
{
|
||||
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
}
|
||||
|
||||
var inputNumber = 0;
|
||||
var inputKeys = new List<string>();
|
||||
|
||||
var inputNumberFeedback = new IntFeedback(() => inputNumber);
|
||||
|
||||
// Two way feedbacks
|
||||
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
|
||||
|
||||
if (twoWayDisplay != null)
|
||||
{
|
||||
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
|
||||
|
||||
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Information, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
|
||||
|
||||
|
||||
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
|
||||
}
|
||||
|
||||
// Power Off
|
||||
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOff();
|
||||
});
|
||||
|
||||
var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase;
|
||||
if (twoWayDisplayDevice != null)
|
||||
{
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!a.BoolValue)
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
inputNumber = 0;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
|
||||
}
|
||||
|
||||
// PowerOn
|
||||
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 0;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOn();
|
||||
});
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
|
||||
{
|
||||
if (i < joinMap.InputNamesOffset.JoinSpan)
|
||||
{
|
||||
inputKeys.Add(displayDevice.InputPorts[i].Key);
|
||||
var tempKey = inputKeys.ElementAt(i);
|
||||
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
|
||||
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
|
||||
Debug.LogMessage(LogEventLevel.Verbose, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
|
||||
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
|
||||
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
|
||||
}
|
||||
else
|
||||
Debug.LogMessage(LogEventLevel.Information, displayDevice, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
|
||||
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
|
||||
}
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
|
||||
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
|
||||
{
|
||||
if (a == 0)
|
||||
{
|
||||
displayDevice.PowerOff();
|
||||
inputNumber = 0;
|
||||
}
|
||||
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
|
||||
{
|
||||
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
|
||||
inputNumber = a;
|
||||
}
|
||||
else if (a == 102)
|
||||
{
|
||||
displayDevice.PowerToggle();
|
||||
|
||||
}
|
||||
if (twoWayDisplay != null)
|
||||
inputNumberFeedback.FireUpdate();
|
||||
});
|
||||
|
||||
|
||||
var volumeDisplay = displayDevice as IBasicVolumeControls;
|
||||
if (volumeDisplay == null) return;
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
|
||||
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
|
||||
|
||||
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
|
||||
|
||||
if (volumeDisplayWithFeedback == null) return;
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
|
||||
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
|
||||
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Obsolete("Please use PepperDash.Essentials.Devices.Common, this will be removed in 2.1")]
|
||||
public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback
|
||||
{
|
||||
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||
|
||||
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||
|
||||
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||
|
||||
|
||||
// public static MockDisplay DefaultDisplay
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// if (_DefaultDisplay == null)
|
||||
// _DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||
// return _DefaultDisplay;
|
||||
// }
|
||||
//}
|
||||
//static MockDisplay _DefaultDisplay;
|
||||
|
||||
public TwoWayDisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
||||
|
||||
WarmupTime = 7000;
|
||||
CooldownTime = 15000;
|
||||
|
||||
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||
|
||||
Feedbacks.Add(CurrentInputFeedback);
|
||||
Feedbacks.Add(PowerIsOnFeedback);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||
|
||||
}
|
||||
|
||||
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (UsageTracker != null)
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue)
|
||||
UsageTracker.StartDeviceUsage();
|
||||
else
|
||||
UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
protected void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ using Crestron.SimplSharpPro.Fusion;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -20,7 +19,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider
|
||||
{
|
||||
private readonly EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap;
|
||||
protected EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap;
|
||||
|
||||
private const string RemoteOccupancyXml = "<Occupancy><Type>Local</Type><State>{0}</State></Occupancy>";
|
||||
private readonly bool _guidFileExists;
|
||||
@@ -30,15 +29,15 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
protected StringSigData CurrentRoomSourceNameSig;
|
||||
|
||||
private readonly FusionCustomPropertiesBridge CustomPropertiesBridge = new FusionCustomPropertiesBridge();
|
||||
public FusionCustomPropertiesBridge CustomPropertiesBridge = new FusionCustomPropertiesBridge();
|
||||
protected FusionOccupancySensorAsset FusionOccSensor;
|
||||
private readonly FusionRemoteOccupancySensor FusionRemoteOccSensor;
|
||||
protected FusionRemoteOccupancySensor FusionRemoteOccSensor;
|
||||
|
||||
protected FusionRoom FusionRoom;
|
||||
protected Dictionary<int, FusionAsset> FusionStaticAssets;
|
||||
private readonly long PushNotificationTimeout = 5000;
|
||||
private readonly IEssentialsRoom Room;
|
||||
private readonly long SchedulePollInterval = 300000;
|
||||
public long PushNotificationTimeout = 5000;
|
||||
protected IEssentialsRoom Room;
|
||||
public long SchedulePollInterval = 300000;
|
||||
|
||||
private Event _currentMeeting;
|
||||
private RoomSchedule _currentSchedule;
|
||||
@@ -86,7 +85,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
#region Default Display Source Sigs
|
||||
|
||||
private readonly BooleanSigData[] _source = new BooleanSigData[10];
|
||||
private BooleanSigData[] _source = new BooleanSigData[10];
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -152,8 +151,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
ReadGuidFile(guidFilePath);
|
||||
}
|
||||
|
||||
var occupancyRoom = Room as IRoomOccupancy;
|
||||
|
||||
if (Room is IRoomOccupancy occupancyRoom)
|
||||
if (occupancyRoom != null)
|
||||
{
|
||||
if (occupancyRoom.RoomOccupancy != null)
|
||||
{
|
||||
@@ -367,7 +367,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName,
|
||||
eSigIoMask.InputSigOnly);
|
||||
// Don't think we need to get current status of this as nothing should be alive yet.
|
||||
if (Room is IHasCurrentSourceInfoChange hasCurrentSourceInfoChange)
|
||||
var hasCurrentSourceInfoChange = Room as IHasCurrentSourceInfoChange;
|
||||
if (hasCurrentSourceInfoChange != null)
|
||||
{
|
||||
hasCurrentSourceInfoChange.CurrentSourceChange += Room_CurrentSourceInfoChange;
|
||||
}
|
||||
@@ -376,7 +377,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(Room.PowerOnToDefaultOrLastSource);
|
||||
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() =>
|
||||
{
|
||||
if (Room is IRunRouteAction runRouteAction)
|
||||
var runRouteAction = Room as IRunRouteAction;
|
||||
if (runRouteAction != null)
|
||||
{
|
||||
runRouteAction.RunRouteAction("roomOff", Room.SourceListKey);
|
||||
}
|
||||
@@ -658,7 +660,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
var extendTime = _currentMeeting.dtEnd - DateTime.Now;
|
||||
var extendMinutesRaw = extendTime.TotalMinutes;
|
||||
|
||||
extendMinutes += (int) Math.Round(extendMinutesRaw);
|
||||
extendMinutes = extendMinutes + (int) Math.Round(extendMinutesRaw);
|
||||
}
|
||||
|
||||
|
||||
@@ -899,7 +901,12 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
}
|
||||
}
|
||||
RoomInfoChange?.Invoke(this, new EventArgs());
|
||||
|
||||
var handler = RoomInfoChange;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
|
||||
CustomPropertiesBridge.EvaluateRoomInfo(Room.Key, roomInformation);
|
||||
}
|
||||
@@ -1007,7 +1014,12 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
|
||||
// Fire Schedule Change Event
|
||||
ScheduleChange?.Invoke(this, new ScheduleChangeEventArgs { Schedule = _currentSchedule });
|
||||
var handler = ScheduleChange;
|
||||
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new ScheduleChangeEventArgs {Schedule = _currentSchedule});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1079,7 +1091,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
}
|
||||
|
||||
var laptops = dict.Where(d => d.Value.SourceDevice is IRoutingSource);
|
||||
var laptops = dict.Where(d => d.Value.SourceDevice is Devices.Laptop);
|
||||
i = 1;
|
||||
foreach (var kvp in laptops)
|
||||
{
|
||||
@@ -1111,7 +1123,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
/// <param name="e"></param>
|
||||
protected void UsageTracker_DeviceUsageEnded(object sender, DeviceUsageEventArgs e)
|
||||
{
|
||||
if (!(sender is UsageTracking deviceTracker))
|
||||
var deviceTracker = sender as UsageTracking;
|
||||
|
||||
if (deviceTracker == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1154,7 +1168,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
// And respond to selection in Fusion
|
||||
sigD.OutputSig.SetSigFalseAction(() =>
|
||||
{
|
||||
if (Room is IRunRouteAction runRouteAction)
|
||||
var runRouteAction = Room as IRunRouteAction;
|
||||
if (runRouteAction != null)
|
||||
{
|
||||
runRouteAction.RunRouteAction(routeKey, Room.SourceListKey);
|
||||
}
|
||||
@@ -1198,11 +1213,12 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
//uint attrNum = Convert.ToUInt32(keyNum);
|
||||
|
||||
// Check for UI devices
|
||||
if (dev is IHasBasicTriListWithSmartObject uiDev)
|
||||
var uiDev = dev as IHasBasicTriListWithSmartObject;
|
||||
if (uiDev != null)
|
||||
{
|
||||
if (uiDev.Panel is Crestron.SimplSharpPro.UI.XpanelForSmartGraphics)
|
||||
{
|
||||
attrNum += touchpanelNum;
|
||||
attrNum = attrNum + touchpanelNum;
|
||||
|
||||
if (attrNum > JoinMap.XpanelOnlineStart.JoinSpan)
|
||||
{
|
||||
@@ -1215,7 +1231,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
else
|
||||
{
|
||||
attrNum += xpanelNum;
|
||||
attrNum = attrNum + xpanelNum;
|
||||
|
||||
if (attrNum > JoinMap.TouchpanelOnlineStart.JoinSpan)
|
||||
{
|
||||
@@ -1229,9 +1245,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
|
||||
//else
|
||||
if (dev is IDisplay)
|
||||
if (dev is DisplayBase)
|
||||
{
|
||||
attrNum += displayNum;
|
||||
attrNum = attrNum + displayNum;
|
||||
if (attrNum > JoinMap.DisplayOnlineStart.JoinSpan)
|
||||
{
|
||||
continue;
|
||||
@@ -1273,21 +1289,23 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
//Setup Display Usage Monitoring
|
||||
|
||||
var displays = DeviceManager.AllDevices.Where(d => d is IDisplay);
|
||||
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
|
||||
|
||||
// Consider updating this in multiple display systems
|
||||
|
||||
foreach (var display in displays.Cast<IDisplay>())
|
||||
foreach (var display in displays.Cast<DisplayBase>())
|
||||
{
|
||||
display.UsageTracker = new UsageTracking(display as Device) {UsageIsTracked = true};
|
||||
display.UsageTracker = new UsageTracking(display) {UsageIsTracked = true};
|
||||
display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||
}
|
||||
|
||||
if (!(Room is IHasDefaultDisplay hasDefaultDisplay))
|
||||
var hasDefaultDisplay = Room as IHasDefaultDisplay;
|
||||
if (hasDefaultDisplay == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(hasDefaultDisplay.DefaultDisplay is IDisplay defaultDisplay))
|
||||
var defaultDisplay = hasDefaultDisplay.DefaultDisplay as DisplayBase;
|
||||
if (defaultDisplay == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Cannot link null display to Fusion because default display is null");
|
||||
return;
|
||||
@@ -1339,7 +1357,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
|
||||
if (defaultDisplay is IHasPowerControlWithFeedback defaultTwoWayDisplay)
|
||||
var defaultTwoWayDisplay = defaultDisplay as IHasPowerControlWithFeedback;
|
||||
if (defaultTwoWayDisplay != null)
|
||||
{
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
if (defaultDisplay is IDisplayUsage)
|
||||
@@ -1351,8 +1370,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
|
||||
// Use extension methods
|
||||
dispAsset.TrySetMakeModel(defaultDisplay as Device);
|
||||
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay as Device);
|
||||
dispAsset.TrySetMakeModel(defaultDisplay);
|
||||
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -1367,12 +1386,13 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
/// <param name="display"></param>
|
||||
/// <param name="displayIndex"></param>
|
||||
/// a
|
||||
protected virtual void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, IDisplay display)
|
||||
protected virtual void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display)
|
||||
{
|
||||
var displayName = string.Format("Display {0} - ", displayIndex);
|
||||
|
||||
|
||||
if (!(Room is IHasDefaultDisplay hasDefaultDisplay) || display != hasDefaultDisplay.DefaultDisplay)
|
||||
var hasDefaultDisplay = Room as IHasDefaultDisplay;
|
||||
if (hasDefaultDisplay == null || display != hasDefaultDisplay.DefaultDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1381,7 +1401,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
eSigIoMask.InputOutputSig);
|
||||
defaultDisplayVolume.OutputSig.UserObject = new Action<ushort>(b =>
|
||||
{
|
||||
if (!(display is IBasicVolumeWithFeedback basicVolumeWithFeedback))
|
||||
var basicVolumeWithFeedback = display as IBasicVolumeWithFeedback;
|
||||
if (basicVolumeWithFeedback == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1414,7 +1435,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
});
|
||||
|
||||
|
||||
if (display is IHasPowerControlWithFeedback defaultTwoWayDisplay)
|
||||
var defaultTwoWayDisplay = display as IHasPowerControlWithFeedback;
|
||||
if (defaultTwoWayDisplay != null)
|
||||
{
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkComplementInputSig(defaultDisplayPowerOff.InputSig);
|
||||
@@ -1427,7 +1449,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
if (Room is IRunRouteAction runRouteAction)
|
||||
var runRouteAction = Room as IRunRouteAction;
|
||||
if (runRouteAction != null)
|
||||
{
|
||||
runRouteAction.RunRouteAction("roomOff", Room.SourceListKey);
|
||||
}
|
||||
@@ -1441,7 +1464,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
_errorMessageRollUp = new StatusMonitorCollection(this);
|
||||
foreach (var dev in DeviceManager.GetDevices())
|
||||
{
|
||||
if (dev is ICommunicationMonitor md)
|
||||
var md = dev as ICommunicationMonitor;
|
||||
if (md != null)
|
||||
{
|
||||
_errorMessageRollUp.AddMonitor(md.CommunicationMonitor);
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Adding '{0}' to room's overall error monitor",
|
||||
@@ -1507,8 +1531,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
// Tie to method on occupancy object
|
||||
//occSensorShutdownMinutes.OutputSig.UserObject(new Action(ushort)(b => Room.OccupancyObj.SetShutdownMinutes(b));
|
||||
|
||||
var occRoom = Room as IRoomOccupancy;
|
||||
|
||||
if (Room is IRoomOccupancy occRoom)
|
||||
if (occRoom != null)
|
||||
{
|
||||
occRoom.RoomOccupancy.RoomIsOccupiedFeedback.LinkInputSig(occSensorAsset.RoomOccupied.InputSig);
|
||||
occRoom.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
|
||||
@@ -1575,9 +1600,10 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
// The sig/UO method: Need separate handlers for fixed and user sigs, all flavors,
|
||||
// even though they all contain sigs.
|
||||
|
||||
var sigData = args.UserConfiguredSigDetail as BooleanSigDataFixedName;
|
||||
|
||||
BoolOutputSig outSig;
|
||||
if (args.UserConfiguredSigDetail is BooleanSigDataFixedName sigData)
|
||||
if (sigData != null)
|
||||
{
|
||||
outSig = sigData.OutputSig;
|
||||
if (outSig.UserObject is Action<bool>)
|
||||
@@ -1733,7 +1759,8 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
/// </summary>
|
||||
public static void TrySetMakeModel(this FusionStaticAsset asset, Device device)
|
||||
{
|
||||
if (device is IMakeModel mm)
|
||||
var mm = device as IMakeModel;
|
||||
if (mm != null)
|
||||
{
|
||||
asset.ParamMake.Value = mm.DeviceMake;
|
||||
asset.ParamModel.Value = mm.DeviceModel;
|
||||
|
||||
171
src/PepperDash.Essentials.Core/Lighting/LightingBase.cs
Normal file
171
src/PepperDash.Essentials.Core/Lighting/LightingBase.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Lighting
|
||||
{
|
||||
[Obsolete("Please use PepperDash.Essentials.Devices.Common, this will be removed in 2.1")]
|
||||
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
|
||||
{
|
||||
#region ILightingScenes Members
|
||||
|
||||
public event EventHandler<LightingSceneChangeEventArgs> LightingSceneChange;
|
||||
|
||||
public List<LightingScene> LightingScenes { get; protected set; }
|
||||
|
||||
public LightingScene CurrentLightingScene { get; protected set; }
|
||||
|
||||
public IntFeedback CurrentLightingSceneFeedback { get; protected set; }
|
||||
|
||||
#endregion
|
||||
|
||||
protected LightingBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
LightingScenes = new List<LightingScene>();
|
||||
|
||||
CurrentLightingScene = new LightingScene();
|
||||
//CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); });
|
||||
}
|
||||
|
||||
public abstract void SelectScene(LightingScene scene);
|
||||
|
||||
public void SimulateSceneSelect(string sceneName)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Simulating selection of scene '{0}'", sceneName);
|
||||
|
||||
var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName));
|
||||
|
||||
if (scene != null)
|
||||
{
|
||||
CurrentLightingScene = scene;
|
||||
OnLightingSceneChange();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the IsActive property on each scene and fires the LightingSceneChange event
|
||||
/// </summary>
|
||||
protected void OnLightingSceneChange()
|
||||
{
|
||||
foreach (var scene in LightingScenes)
|
||||
{
|
||||
if (scene == CurrentLightingScene)
|
||||
scene.IsActive = true;
|
||||
|
||||
else
|
||||
scene.IsActive = false;
|
||||
}
|
||||
|
||||
var handler = LightingSceneChange;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
|
||||
}
|
||||
}
|
||||
|
||||
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
|
||||
string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new GenericLightingJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
return LinkLightingToApi(lightingDevice, trilist, joinMap);
|
||||
}
|
||||
|
||||
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
|
||||
|
||||
// GenericLighitng Actions & FeedBack
|
||||
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
|
||||
|
||||
var sceneIndex = 0;
|
||||
foreach (var scene in lightingDevice.LightingScenes)
|
||||
{
|
||||
var index = sceneIndex;
|
||||
|
||||
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + index), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[index]));
|
||||
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)]);
|
||||
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
|
||||
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
|
||||
|
||||
sceneIndex++;
|
||||
}
|
||||
|
||||
trilist.OnlineStatusChange += (sender, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
|
||||
sceneIndex = 0;
|
||||
foreach (var scene in lightingDevice.LightingScenes)
|
||||
{
|
||||
var index = sceneIndex;
|
||||
|
||||
trilist.StringInput[(uint) (joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
|
||||
trilist.BooleanInput[(uint) (joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
|
||||
scene.IsActiveFeedback.FireUpdate();
|
||||
|
||||
sceneIndex++;
|
||||
}
|
||||
};
|
||||
|
||||
return joinMap;
|
||||
}
|
||||
}
|
||||
|
||||
public class LightingScene
|
||||
{
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string ID { get; set; }
|
||||
bool _IsActive;
|
||||
[JsonProperty("isActive", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool IsActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return _IsActive;
|
||||
}
|
||||
set
|
||||
{
|
||||
_IsActive = value;
|
||||
IsActiveFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public BoolFeedback IsActiveFeedback { get; set; }
|
||||
|
||||
public LightingScene()
|
||||
{
|
||||
IsActiveFeedback = new BoolFeedback(new Func<bool>(() => IsActive));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Lighting
|
||||
{
|
||||
public class LightingScene
|
||||
{
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string ID { get; set; }
|
||||
bool _IsActive;
|
||||
[JsonProperty("isActive", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool IsActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return _IsActive;
|
||||
}
|
||||
set
|
||||
{
|
||||
_IsActive = value;
|
||||
IsActiveFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public BoolFeedback IsActiveFeedback { get; set; }
|
||||
|
||||
public LightingScene()
|
||||
{
|
||||
IsActiveFeedback = new BoolFeedback(new Func<bool>(() => IsActive));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,16 +151,17 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
if (MonitorBytesReceived)
|
||||
{
|
||||
Client.BytesReceived -= Client_BytesReceived;
|
||||
Client.BytesReceived += Client_BytesReceived;
|
||||
Client.BytesReceived += Client_BytesReceived;
|
||||
}
|
||||
else
|
||||
{
|
||||
Client.TextReceived -= Client_TextReceived;
|
||||
Client.TextReceived += Client_TextReceived;
|
||||
}
|
||||
|
||||
BeginPolling();
|
||||
if (!IsSocket)
|
||||
{
|
||||
BeginPolling();
|
||||
}
|
||||
}
|
||||
|
||||
void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<AssemblyName>PepperDash_Essentials_Core</AssemblyName>
|
||||
<RootNamespace>PepperDash.Essentials.Core</RootNamespace>
|
||||
@@ -14,6 +13,7 @@
|
||||
<PackageId>PepperDash.Essentials.Core</PackageId>
|
||||
<InformationalVersion>$(Version)</InformationalVersion>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>2.0.0-local</Version>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
@@ -31,7 +31,4 @@
|
||||
<ItemGroup>
|
||||
<None Include="Crestron\CrestronGenericBaseDevice.cs.orig" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Display\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -4,7 +4,6 @@ using System.Globalization;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Touchpanels
|
||||
@@ -35,9 +34,9 @@ namespace PepperDash.Essentials.Core.Touchpanels
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "touchpanel registration response: {0}", registrationResponse);
|
||||
}
|
||||
|
||||
_touchpanel.BaseEvent += Touchpanel_BaseEvent;
|
||||
_touchpanel.ButtonStateChange += Touchpanel_ButtonStateChange;
|
||||
_touchpanel.PanelStateChange += Touchpanel_PanelStateChange;
|
||||
_touchpanel.BaseEvent += _touchpanel_BaseEvent;
|
||||
_touchpanel.ButtonStateChange += _touchpanel_ButtonStateChange;
|
||||
_touchpanel.PanelStateChange += _touchpanel_PanelStateChange;
|
||||
|
||||
_buttons = buttons;
|
||||
if (_buttons == null)
|
||||
@@ -75,9 +74,10 @@ namespace PepperDash.Essentials.Core.Touchpanels
|
||||
return;
|
||||
}
|
||||
|
||||
TryParseInt(key, out int buttonNumber);
|
||||
int buttonNumber;
|
||||
TryParseInt(key, out buttonNumber);
|
||||
|
||||
var buttonEventTypes = config.EventTypes;
|
||||
var buttonEventTypes = config.EventTypes;
|
||||
BoolOutputSig enabledFb = null;
|
||||
BoolOutputSig disabledFb = null;
|
||||
|
||||
@@ -161,10 +161,11 @@ namespace PepperDash.Essentials.Core.Touchpanels
|
||||
return;
|
||||
}
|
||||
|
||||
TryParseInt(key, out int buttonNumber);
|
||||
int buttonNumber;
|
||||
TryParseInt(key, out buttonNumber);
|
||||
|
||||
// Link up the button feedbacks to the specified device feedback
|
||||
var buttonFeedback = config.Feedback;
|
||||
// Link up the button feedbacks to the specified device feedback
|
||||
var buttonFeedback = config.Feedback;
|
||||
if (buttonFeedback == null || string.IsNullOrEmpty(buttonFeedback.DeviceKey))
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Button '{0}' feedback not configured, skipping.",
|
||||
@@ -176,14 +177,15 @@ namespace PepperDash.Essentials.Core.Touchpanels
|
||||
|
||||
try
|
||||
{
|
||||
if (!(DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) is Device device))
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Button '{0}' feedback deviceKey '{1}' not found.",
|
||||
key, buttonFeedback.DeviceKey);
|
||||
return;
|
||||
}
|
||||
var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device;
|
||||
if (device == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Button '{0}' feedback deviceKey '{1}' not found.",
|
||||
key, buttonFeedback.DeviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName);
|
||||
deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName);
|
||||
if (deviceFeedback == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "Button '{0}' feedbackName property '{1}' not found.",
|
||||
@@ -222,37 +224,38 @@ namespace PepperDash.Essentials.Core.Touchpanels
|
||||
}
|
||||
|
||||
var boolFeedback = deviceFeedback as BoolFeedback;
|
||||
var intFeedback = deviceFeedback as IntFeedback;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case ("power"):
|
||||
{
|
||||
boolFeedback?.LinkCrestronFeedback(_touchpanel.FeedbackPower);
|
||||
break;
|
||||
}
|
||||
case ("volumeup"):
|
||||
case ("volumedown"):
|
||||
case ("volumefeedback"):
|
||||
{
|
||||
if (deviceFeedback is IntFeedback intFeedback)
|
||||
{
|
||||
var volumeFeedback = intFeedback;
|
||||
volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ("mute"):
|
||||
{
|
||||
boolFeedback?.LinkCrestronFeedback(_touchpanel.FeedbackMute);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
boolFeedback?.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (key)
|
||||
{
|
||||
case ("power"):
|
||||
{
|
||||
if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackPower);
|
||||
break;
|
||||
}
|
||||
case ("volumeup"):
|
||||
case ("volumedown"):
|
||||
case ("volumefeedback"):
|
||||
{
|
||||
if (intFeedback != null)
|
||||
{
|
||||
var volumeFeedback = intFeedback;
|
||||
volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ("mute"):
|
||||
{
|
||||
if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackMute);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try parse int helper method
|
||||
@@ -274,12 +277,12 @@ namespace PepperDash.Essentials.Core.Touchpanels
|
||||
}
|
||||
}
|
||||
|
||||
private void Touchpanel_BaseEvent(GenericBase device, BaseEventArgs args)
|
||||
private void _touchpanel_BaseEvent(GenericBase device, BaseEventArgs args)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "BaseEvent: eventId-'{0}', index-'{1}'", args.EventId, args.Index);
|
||||
}
|
||||
|
||||
private void Touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args)
|
||||
private void _touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "ButtonStateChange: buttonNumber-'{0}' buttonName-'{1}', buttonState-'{2}'", args.Button.Number, args.Button.Name, args.NewButtonState);
|
||||
var type = args.NewButtonState.ToString();
|
||||
@@ -294,7 +297,7 @@ namespace PepperDash.Essentials.Core.Touchpanels
|
||||
}
|
||||
}
|
||||
|
||||
private void Touchpanel_PanelStateChange(GenericBase device, BaseEventArgs args)
|
||||
private void _touchpanel_PanelStateChange(GenericBase device, BaseEventArgs args)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, this, "PanelStateChange: eventId-'{0}', index-'{1}'", args.EventId, args.Index);
|
||||
}
|
||||
@@ -307,7 +310,7 @@ namespace PepperDash.Essentials.Core.Touchpanels
|
||||
/// <param name="type"></param>
|
||||
public void Press(string buttonKey, string type)
|
||||
{
|
||||
this.LogVerbose("Press: buttonKey-'{buttonKey}', type-'{type}'", buttonKey, type);
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Press: buttonKey-'{0}', type-'{1}'", buttonKey, type);
|
||||
|
||||
// TODO: In future, consider modifying this to generate actions at device activation time
|
||||
// to prevent the need to dynamically call the method via reflection on each button press
|
||||
@@ -322,12 +325,18 @@ namespace PepperDash.Essentials.Core.Touchpanels
|
||||
|
||||
public void ListButtons()
|
||||
{
|
||||
this.LogVerbose("MPC3 Controller {0} - Available Buttons", Key);
|
||||
var line = new string('-', 35);
|
||||
|
||||
Debug.Console(0, this, line);
|
||||
|
||||
Debug.Console(0, this, "MPC3 Controller {0} - Available Butons", Key);
|
||||
|
||||
foreach (var button in _buttons)
|
||||
{
|
||||
this.LogVerbose("Key: {key}", button.Key);
|
||||
Debug.Console(0, this, "Key: {0}", button.Key);
|
||||
}
|
||||
|
||||
Debug.Console(0, this, line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,23 +119,23 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(DeviceManager.GetDeviceForKey(body.DeviceKey) is IStreamDebugging device))
|
||||
{
|
||||
context.Response.StatusCode = 404;
|
||||
context.Response.StatusDescription = "Not Found";
|
||||
context.Response.End();
|
||||
var device = DeviceManager.GetDeviceForKey(body.DeviceKey) as IStreamDebugging;
|
||||
if (device == null)
|
||||
{
|
||||
context.Response.StatusCode = 404;
|
||||
context.Response.StatusDescription = "Not Found";
|
||||
context.Response.End();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
eStreamDebuggingSetting debugSetting;
|
||||
return;
|
||||
}
|
||||
|
||||
eStreamDebuggingSetting debugSetting;
|
||||
try
|
||||
{
|
||||
debugSetting = (eStreamDebuggingSetting) Enum.Parse(typeof (eStreamDebuggingSetting), body.Setting, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception handling set debug request");
|
||||
context.Response.StatusCode = 500;
|
||||
context.Response.StatusDescription = "Internal Server Error";
|
||||
context.Response.End();
|
||||
@@ -161,7 +161,6 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception handling set debug request");
|
||||
context.Response.StatusCode = 500;
|
||||
context.Response.StatusDescription = "Internal Server Error";
|
||||
context.Response.End();
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IHasPowerControlWithFeedback, IBridgeAdvanced, IHasCameraFocusControl, IHasAutoFocusMode
|
||||
{
|
||||
private readonly CameraViscaPropertiesConfig PropertiesConfig;
|
||||
CameraViscaPropertiesConfig PropertiesConfig;
|
||||
|
||||
public IBasicCommunication Communication { get; private set; }
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
/// <summary>
|
||||
/// Used to store the actions to parse inquiry responses as the inquiries are sent
|
||||
/// </summary>
|
||||
private readonly CrestronQueue<Action<byte[]>> InquiryResponseQueue;
|
||||
private CrestronQueue<Action<byte[]>> InquiryResponseQueue;
|
||||
|
||||
/// <summary>
|
||||
/// Camera ID (Default 1)
|
||||
@@ -45,7 +45,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
public byte PanSpeedFast = 0x13;
|
||||
public byte TiltSpeedFast = 0x13;
|
||||
|
||||
// private bool IsMoving;
|
||||
private bool IsMoving;
|
||||
private bool IsZooming;
|
||||
|
||||
bool _powerIsOn;
|
||||
@@ -101,17 +101,18 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom | eCameraCapabilities.Focus;
|
||||
|
||||
Communication = comm;
|
||||
if (comm is ISocketStatus socket)
|
||||
{
|
||||
// This instance uses IP control
|
||||
socket.ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(Socket_ConnectionChange);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This instance uses RS-232 control
|
||||
}
|
||||
var socket = comm as ISocketStatus;
|
||||
if (socket != null)
|
||||
{
|
||||
// This instance uses IP control
|
||||
socket.ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(socket_ConnectionChange);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This instance uses RS-232 control
|
||||
}
|
||||
|
||||
Communication.BytesReceived += new EventHandler<GenericCommMethodReceiveBytesArgs>(Communication_BytesReceived);
|
||||
Communication.BytesReceived += new EventHandler<GenericCommMethodReceiveBytesArgs>(Communication_BytesReceived);
|
||||
PowerIsOnFeedback = new BoolFeedback(() => { return PowerIsOn; });
|
||||
CameraIsOffFeedback = new BoolFeedback(() => { return !PowerIsOn; });
|
||||
|
||||
@@ -174,7 +175,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
|
||||
void Socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
|
||||
void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString());
|
||||
|
||||
@@ -448,12 +449,12 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
public void PanLeft()
|
||||
{
|
||||
SendPanTiltCommand(new byte[] {0x01, 0x03}, false);
|
||||
// IsMoving = true;
|
||||
IsMoving = true;
|
||||
}
|
||||
public void PanRight()
|
||||
{
|
||||
SendPanTiltCommand(new byte[] { 0x02, 0x03 }, false);
|
||||
// IsMoving = true;
|
||||
IsMoving = true;
|
||||
}
|
||||
public void PanStop()
|
||||
{
|
||||
@@ -462,12 +463,12 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
public void TiltDown()
|
||||
{
|
||||
SendPanTiltCommand(new byte[] { 0x03, 0x02 }, false);
|
||||
// IsMoving = true;
|
||||
IsMoving = true;
|
||||
}
|
||||
public void TiltUp()
|
||||
{
|
||||
SendPanTiltCommand(new byte[] { 0x03, 0x01 }, false);
|
||||
// IsMoving = true;
|
||||
IsMoving = true;
|
||||
}
|
||||
public void TiltStop()
|
||||
{
|
||||
@@ -506,7 +507,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
StopSpeedTimer();
|
||||
SendPanTiltCommand(new byte[] { 0x03, 0x03 }, false);
|
||||
// IsMoving = false;
|
||||
IsMoving = false;
|
||||
}
|
||||
}
|
||||
public void PositionHome()
|
||||
|
||||
@@ -40,9 +40,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
|
||||
private int _meetingWarningMinutes = 5;
|
||||
|
||||
//private Meeting _previousChangedMeeting;
|
||||
private Meeting _previousChangedMeeting;
|
||||
|
||||
//private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown;
|
||||
private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown;
|
||||
|
||||
public int MeetingWarningMinutes
|
||||
{
|
||||
@@ -62,11 +62,16 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
set
|
||||
{
|
||||
_meetings = value;
|
||||
MeetingsListHasChanged?.Invoke(this, new EventArgs());
|
||||
|
||||
var handler = MeetingsListHasChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly CTimer _scheduleChecker;
|
||||
private CTimer _scheduleChecker;
|
||||
|
||||
public CodecScheduleAwareness()
|
||||
{
|
||||
@@ -94,7 +99,12 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
// Add this change type to the NotifiedChangeTypes
|
||||
meeting.NotifiedChangeTypes |= changeType;
|
||||
MeetingEventChange?.Invoke(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
|
||||
|
||||
var handler = MeetingEventChange;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@ using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -13,7 +12,12 @@ using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
{
|
||||
public abstract class DisplayBase : EssentialsDevice, IDisplay
|
||||
public abstract class DisplayBase : EssentialsDevice
|
||||
, IHasFeedback
|
||||
, IRoutingSinkWithSwitching
|
||||
, IHasPowerControl
|
||||
, IWarmingCooling
|
||||
, IUsageTracking
|
||||
{
|
||||
private RoutingInputPort _currentInputPort;
|
||||
public RoutingInputPort CurrentInputPort
|
||||
|
||||
@@ -12,7 +12,7 @@ using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
{
|
||||
public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs<string>, IRoutingSinkWithSwitchingWithInputPort, IHasPowerControlWithFeedback
|
||||
public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs<string, string>, IRoutingSinkWithSwitchingWithInputPort, IHasPowerControlWithFeedback
|
||||
{
|
||||
public ISelectableItems<string> Inputs { get; private set; }
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Lighting
|
||||
{
|
||||
[Obsolete("Please use PepperDash.Essentials.Devices.Common, this will be removed in 2.1")]
|
||||
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
|
||||
{
|
||||
#region ILightingScenes Members
|
||||
@@ -67,7 +68,12 @@ namespace PepperDash.Essentials.Devices.Common.Lighting
|
||||
else
|
||||
scene.IsActive = false;
|
||||
}
|
||||
LightingSceneChange?.Invoke(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
|
||||
|
||||
var handler = LightingSceneChange;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
|
||||
}
|
||||
}
|
||||
|
||||
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<AssemblyName>Essentials Devices Common</AssemblyName>
|
||||
<RootNamespace>PepperDash.Essentials.Devices.Common</RootNamespace>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<Title>PepperDash Essentials Devices Common</Title>
|
||||
<PackageId>PepperDash.Essentials.Devices.Common</PackageId>
|
||||
<Version>2.0.0-local</Version>
|
||||
<InformationalVersion>$(Version)</InformationalVersion>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -31,9 +31,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
protected const int MaxParticipants = 50;
|
||||
private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
|
||||
|
||||
private readonly IHasDirectory _directoryCodec;
|
||||
private readonly BasicTriList _directoryTrilist;
|
||||
private readonly VideoCodecControllerJoinMap _directoryJoinmap;
|
||||
private IHasDirectory _directoryCodec;
|
||||
private BasicTriList _directoryTrilist;
|
||||
private VideoCodecControllerJoinMap _directoryJoinmap;
|
||||
|
||||
protected string _timeFormatSpecifier;
|
||||
protected string _dateFormatSpecifier;
|
||||
@@ -216,7 +216,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
/// <param name="item"></param>
|
||||
protected virtual void OnCallStatusChange(CodecActiveCallItem item)
|
||||
{
|
||||
CallStatusChange?.Invoke(this, new CodecCallStatusItemChangeEventArgs(item));
|
||||
var handler = CallStatusChange;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new CodecCallStatusItemChangeEventArgs(item));
|
||||
}
|
||||
|
||||
PrivacyModeIsOnFeedback.FireUpdate();
|
||||
|
||||
@@ -248,8 +252,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
try
|
||||
{
|
||||
IsReady = true;
|
||||
IsReadyChange?.Invoke(this, new EventArgs());
|
||||
}
|
||||
var h = IsReadyChange;
|
||||
if (h != null)
|
||||
{
|
||||
h(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, this, "Error in SetIsReady() : {0}", e);
|
||||
@@ -301,7 +309,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
joinMap.SetCustomJoinData(customJoins);
|
||||
}
|
||||
|
||||
bridge?.AddJoinMap(Key, joinMap);
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
|
||||
LinkVideoCodecToApi(codec, trilist, joinMap);
|
||||
|
||||
@@ -519,10 +530,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
|
||||
var autoCodec = codec as IHasCameraAutoMode;
|
||||
|
||||
if (!(codec is IHasCameraAutoMode autoCodec)) return;
|
||||
if (autoCodec == null) return;
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
};
|
||||
|
||||
@@ -536,10 +548,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
|
||||
var autoModeCodec = codec as IHasCameraAutoMode;
|
||||
|
||||
if (!(codec is IHasCameraAutoMode autoModeCodec)) return;
|
||||
if (autoModeCodec == null) return;
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
}
|
||||
|
||||
@@ -636,7 +649,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
var p = participant;
|
||||
if (index > MaxParticipants) break;
|
||||
|
||||
if (this is IHasParticipantAudioMute audioMuteCodec)
|
||||
var audioMuteCodec = this as IHasParticipantAudioMute;
|
||||
if (audioMuteCodec != null)
|
||||
{
|
||||
trilist.SetSigFalseAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index,
|
||||
() => audioMuteCodec.ToggleAudioForParticipant(p.UserId));
|
||||
@@ -645,7 +659,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
() => audioMuteCodec.ToggleVideoForParticipant(p.UserId));
|
||||
}
|
||||
|
||||
if (this is IHasParticipantPinUnpin pinCodec)
|
||||
var pinCodec = this as IHasParticipantPinUnpin;
|
||||
if (pinCodec != null)
|
||||
{
|
||||
trilist.SetSigFalseAction(joinMap.ParticipantPinToggleStart.JoinNumber + index,
|
||||
() => pinCodec.ToggleParticipantPinState(p.UserId, pinCodec.ScreenIndexToPinUserTo));
|
||||
@@ -1074,25 +1089,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
// Allow auto dial of selected line. Always dials first contact method
|
||||
if (!trilist.GetBool(joinMap.DirectoryDisableAutoDialSelectedLine.JoinNumber))
|
||||
{
|
||||
if (_selectedDirectoryItem is IInvitableContact invitableEntry)
|
||||
var invitableEntry = _selectedDirectoryItem as IInvitableContact;
|
||||
|
||||
if (invitableEntry != null)
|
||||
{
|
||||
Dial(invitableEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
var entryToDial = _selectedDirectoryItem as DirectoryContact;
|
||||
|
||||
trilist.SetString(joinMap.DirectoryEntrySelectedNumber.JoinNumber,
|
||||
trilist.SetString(joinMap.DirectoryEntrySelectedNumber.JoinNumber,
|
||||
selectedContact != null ? selectedContact.ContactMethods[0].Number : string.Empty);
|
||||
|
||||
if (!(_selectedDirectoryItem is DirectoryContact entryToDial)) return;
|
||||
if (entryToDial == null) return;
|
||||
|
||||
Dial(entryToDial.ContactMethods[0].Number);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If auto dial is disabled...
|
||||
var entryToDial = _selectedDirectoryItem as DirectoryContact;
|
||||
|
||||
if (!(_selectedDirectoryItem is DirectoryContact entryToDial))
|
||||
if (entryToDial == null)
|
||||
{
|
||||
// Clear out values and actions from last selected item
|
||||
trilist.SetUshort(joinMap.SelectedContactMethodCount.JoinNumber, 0);
|
||||
@@ -1277,76 +1296,78 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
trilist.SetUshort(joinMap.ConnectedCallCount.JoinNumber, (ushort)ActiveCalls.Count);
|
||||
};
|
||||
|
||||
if (this is IJoinCalls joinCodec)
|
||||
{
|
||||
trilist.SetSigFalseAction(joinMap.JoinAllCalls.JoinNumber, () => joinCodec.JoinAllCalls());
|
||||
var joinCodec = this as IJoinCalls;
|
||||
if (joinCodec != null)
|
||||
{
|
||||
trilist.SetSigFalseAction(joinMap.JoinAllCalls.JoinNumber, () => joinCodec.JoinAllCalls());
|
||||
|
||||
for (int i = 0; i < joinMap.JoinCallStart.JoinSpan; i++)
|
||||
{
|
||||
trilist.SetSigFalseAction((uint)(joinMap.JoinCallStart.JoinNumber + i), () =>
|
||||
{
|
||||
var call = ActiveCalls[i];
|
||||
if (call != null)
|
||||
{
|
||||
joinCodec.JoinCall(call);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "[Join Call] Unable to find call at index '{0}'", i);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < joinMap.JoinCallStart.JoinSpan; i++)
|
||||
{
|
||||
trilist.SetSigFalseAction((uint)(joinMap.JoinCallStart.JoinNumber + i), () =>
|
||||
{
|
||||
var call = ActiveCalls[i];
|
||||
if (call != null)
|
||||
{
|
||||
joinCodec.JoinCall(call);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "[Join Call] Unable to find call at index '{0}'", i);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this is IHasCallHold holdCodec)
|
||||
{
|
||||
trilist.SetSigFalseAction(joinMap.HoldAllCalls.JoinNumber, () =>
|
||||
{
|
||||
foreach (var call in ActiveCalls)
|
||||
{
|
||||
holdCodec.HoldCall(call);
|
||||
}
|
||||
});
|
||||
var holdCodec = this as IHasCallHold;
|
||||
if (holdCodec != null)
|
||||
{
|
||||
trilist.SetSigFalseAction(joinMap.HoldAllCalls.JoinNumber, () =>
|
||||
{
|
||||
foreach (var call in ActiveCalls)
|
||||
{
|
||||
holdCodec.HoldCall(call);
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < joinMap.HoldCallsStart.JoinSpan; i++)
|
||||
{
|
||||
var index = i;
|
||||
for (int i = 0; i < joinMap.HoldCallsStart.JoinSpan; i++)
|
||||
{
|
||||
var index = i;
|
||||
|
||||
trilist.SetSigFalseAction((uint)(joinMap.HoldCallsStart.JoinNumber + index), () =>
|
||||
{
|
||||
if (index < 0 || index >= ActiveCalls.Count) return;
|
||||
trilist.SetSigFalseAction((uint)(joinMap.HoldCallsStart.JoinNumber + index), () =>
|
||||
{
|
||||
if (index < 0 || index >= ActiveCalls.Count) return;
|
||||
|
||||
var call = ActiveCalls[index];
|
||||
if (call != null)
|
||||
{
|
||||
holdCodec.HoldCall(call);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "[Hold Call] Unable to find call at index '{0}'", i);
|
||||
}
|
||||
});
|
||||
var call = ActiveCalls[index];
|
||||
if (call != null)
|
||||
{
|
||||
holdCodec.HoldCall(call);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "[Hold Call] Unable to find call at index '{0}'", i);
|
||||
}
|
||||
});
|
||||
|
||||
trilist.SetSigFalseAction((uint)(joinMap.ResumeCallsStart.JoinNumber + index), () =>
|
||||
{
|
||||
if (index < 0 || index >= ActiveCalls.Count) return;
|
||||
trilist.SetSigFalseAction((uint)(joinMap.ResumeCallsStart.JoinNumber + index), () =>
|
||||
{
|
||||
if (index < 0 || index >= ActiveCalls.Count) return;
|
||||
|
||||
var call = ActiveCalls[index];
|
||||
if (call != null)
|
||||
{
|
||||
holdCodec.ResumeCall(call);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "[Resume Call] Unable to find call at index '{0}'", i);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
var call = ActiveCalls[index];
|
||||
if (call != null)
|
||||
{
|
||||
holdCodec.ResumeCall(call);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "[Resume Call] Unable to find call at index '{0}'", i);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
trilist.OnlineStatusChange += (device, args) =>
|
||||
trilist.OnlineStatusChange += (device, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
|
||||
@@ -1484,45 +1505,48 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
codec.CameraAutoModeIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (codec is IHasCameraOff offCodec)
|
||||
{
|
||||
if (offCodec.CameraIsOffFeedback.BoolValue)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
|
||||
return;
|
||||
}
|
||||
var offCodec = codec as IHasCameraOff;
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
return;
|
||||
}
|
||||
if (offCodec != null)
|
||||
{
|
||||
if (offCodec.CameraIsOffFeedback.BoolValue)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
|
||||
return;
|
||||
}
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
return;
|
||||
}
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
};
|
||||
|
||||
var offModeCodec = codec as IHasCameraOff;
|
||||
|
||||
if (codec is IHasCameraOff offModeCodec)
|
||||
{
|
||||
if (offModeCodec.CameraIsOffFeedback.BoolValue)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
|
||||
return;
|
||||
}
|
||||
if (offModeCodec != null)
|
||||
{
|
||||
if (offModeCodec.CameraIsOffFeedback.BoolValue)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
|
||||
return;
|
||||
}
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
return;
|
||||
}
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
return;
|
||||
}
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
}
|
||||
@@ -1541,58 +1565,64 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
trilist.SetBoolSigAction(joinMap.CameraTiltUp.JoinNumber, (b) =>
|
||||
{
|
||||
if (codec.SelectedCamera == null) return;
|
||||
var camera = codec.SelectedCamera as IHasCameraPtzControl;
|
||||
|
||||
if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return;
|
||||
if (camera == null) return;
|
||||
|
||||
if (b) camera.TiltUp();
|
||||
if (b) camera.TiltUp();
|
||||
else camera.TiltStop();
|
||||
});
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.CameraTiltDown.JoinNumber, (b) =>
|
||||
{
|
||||
if (codec.SelectedCamera == null) return;
|
||||
var camera = codec.SelectedCamera as IHasCameraPtzControl;
|
||||
|
||||
if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return;
|
||||
if (camera == null) return;
|
||||
|
||||
if (b) camera.TiltDown();
|
||||
if (b) camera.TiltDown();
|
||||
else camera.TiltStop();
|
||||
});
|
||||
trilist.SetBoolSigAction(joinMap.CameraPanLeft.JoinNumber, (b) =>
|
||||
{
|
||||
if (codec.SelectedCamera == null) return;
|
||||
var camera = codec.SelectedCamera as IHasCameraPtzControl;
|
||||
|
||||
if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return;
|
||||
if (camera == null) return;
|
||||
|
||||
if (b) camera.PanLeft();
|
||||
if (b) camera.PanLeft();
|
||||
else camera.PanStop();
|
||||
});
|
||||
trilist.SetBoolSigAction(joinMap.CameraPanRight.JoinNumber, (b) =>
|
||||
{
|
||||
if (codec.SelectedCamera == null) return;
|
||||
var camera = codec.SelectedCamera as IHasCameraPtzControl;
|
||||
|
||||
if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return;
|
||||
if (camera == null) return;
|
||||
|
||||
if (b) camera.PanRight();
|
||||
if (b) camera.PanRight();
|
||||
else camera.PanStop();
|
||||
});
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.CameraZoomIn.JoinNumber, (b) =>
|
||||
{
|
||||
if (codec.SelectedCamera == null) return;
|
||||
var camera = codec.SelectedCamera as IHasCameraPtzControl;
|
||||
|
||||
if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return;
|
||||
if (camera == null) return;
|
||||
|
||||
if (b) camera.ZoomIn();
|
||||
if (b) camera.ZoomIn();
|
||||
else camera.ZoomStop();
|
||||
});
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.CameraZoomOut.JoinNumber, (b) =>
|
||||
{
|
||||
if (codec.SelectedCamera == null) return;
|
||||
var camera = codec.SelectedCamera as IHasCameraPtzControl;
|
||||
|
||||
if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return;
|
||||
if (camera == null) return;
|
||||
|
||||
if (b) camera.ZoomOut();
|
||||
if (b) camera.ZoomOut();
|
||||
else camera.ZoomStop();
|
||||
});
|
||||
|
||||
@@ -1600,8 +1630,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
trilist.SetBoolSigAction(joinMap.CameraFocusNear.JoinNumber, (b) =>
|
||||
{
|
||||
if (codec.SelectedCamera == null) return;
|
||||
var camera = codec.SelectedCamera as IHasCameraFocusControl;
|
||||
|
||||
if (!(codec.SelectedCamera is IHasCameraFocusControl camera)) return;
|
||||
if (camera == null) return;
|
||||
|
||||
if (b) camera.FocusNear();
|
||||
else camera.FocusStop();
|
||||
@@ -1610,8 +1641,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
trilist.SetBoolSigAction(joinMap.CameraFocusFar.JoinNumber, (b) =>
|
||||
{
|
||||
if (codec.SelectedCamera == null) return;
|
||||
var camera = codec.SelectedCamera as IHasCameraFocusControl;
|
||||
|
||||
if (!(codec.SelectedCamera is IHasCameraFocusControl camera)) return;
|
||||
if (camera == null) return;
|
||||
|
||||
if (b) camera.FocusFar();
|
||||
else camera.FocusStop();
|
||||
@@ -1620,8 +1652,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
trilist.SetSigFalseAction(joinMap.CameraFocusAuto.JoinNumber, () =>
|
||||
{
|
||||
if (codec.SelectedCamera == null) return;
|
||||
var camera = codec.SelectedCamera as IHasCameraFocusControl;
|
||||
|
||||
if (!(codec.SelectedCamera is IHasCameraFocusControl camera)) return;
|
||||
if (camera == null) return;
|
||||
|
||||
camera.TriggerAutoFocus();
|
||||
});
|
||||
@@ -1740,6 +1773,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
// Following fields only used for Bridging
|
||||
private int _selectedRecentCallItemIndex;
|
||||
private CodecCallHistory.CallHistoryEntry _selectedRecentCallItem;
|
||||
private DirectoryItem _selectedDirectoryItem;
|
||||
|
||||
private void LinkVideoCodecCallHistoryToApi(IHasCallHistory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
@@ -1786,7 +1820,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
// Clear out selected item
|
||||
_selectedRecentCallItemIndex = 0;
|
||||
|
||||
_selectedRecentCallItem = null;
|
||||
trilist.SetUshort(joinMap.SelectRecentCallItem.JoinNumber, 0);
|
||||
trilist.SetString(joinMap.SelectedRecentCallName.JoinNumber, string.Empty);
|
||||
trilist.SetString(joinMap.SelectedRecentCallNumber.JoinNumber, string.Empty);
|
||||
@@ -1895,8 +1929,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
if (value == true)
|
||||
{
|
||||
InitialSyncCompleted?.Invoke(this, new EventArgs());
|
||||
}
|
||||
var handler = InitialSyncCompleted;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
_InitialSyncComplete = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer
|
||||
{
|
||||
public class SourceSelectMessageContent
|
||||
{
|
||||
|
||||
[JsonProperty("sourceListItemKey")]
|
||||
public string SourceListItemKey { get; set; }
|
||||
[JsonProperty("sourceListKey")]
|
||||
public string SourceListKey { get; set; }
|
||||
}
|
||||
|
||||
public class DirectRoute
|
||||
{
|
||||
|
||||
[JsonProperty("sourceKey")]
|
||||
public string SourceKey { get; set; }
|
||||
[JsonProperty("destinationKey")]
|
||||
public string DestinationKey { get; set; }
|
||||
[JsonProperty("signalType")]
|
||||
public eRoutingSignalType SignalType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
public delegate void PressAndHoldAction(bool b);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using System.Linq;
|
||||
using DisplayBase = PepperDash.Essentials.Devices.Common.Displays.DisplayBase;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
public class DisplayBaseMessenger : MessengerBase
|
||||
{
|
||||
private readonly DisplayBase display;
|
||||
|
||||
public DisplayBaseMessenger(string key, string messagePath, DisplayBase device) : base(key, messagePath, device)
|
||||
{
|
||||
display = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
/*AddAction("/powerOn", (id, content) => display.PowerOn());
|
||||
AddAction("/powerOff", (id, content) => display.PowerOff());
|
||||
AddAction("/powerToggle", (id, content) => display.PowerToggle());*/
|
||||
|
||||
AddAction("/inputSelect", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var inputPort = display.InputPorts.FirstOrDefault(i => i.Key == s.Value);
|
||||
|
||||
if (inputPort == null)
|
||||
{
|
||||
this.LogWarning("No input named {inputName} found for {deviceKey}", s, display.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
display.ExecuteSwitch(inputPort.Selector);
|
||||
});
|
||||
|
||||
AddAction("/inputs", (id, content) =>
|
||||
{
|
||||
var inputsList = display.InputPorts.Select(p => p.Key).ToList();
|
||||
|
||||
var messageObject = new MobileControlMessage
|
||||
{
|
||||
Type = MessagePath + "/inputs",
|
||||
Content = JToken.FromObject(new
|
||||
{
|
||||
inputKeys = inputsList,
|
||||
})
|
||||
};
|
||||
|
||||
AppServerController.SendMessageObject(messageObject);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
public class IChannelMessenger : MessengerBase
|
||||
{
|
||||
private readonly IChannel channelDevice;
|
||||
|
||||
public IChannelMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
channelDevice = device as IChannel;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/chanUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => channelDevice?.ChannelUp(b)));
|
||||
|
||||
AddAction("/chanDown", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => channelDevice?.ChannelDown(b)));
|
||||
AddAction("/lastChan", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => channelDevice?.LastChannel(b)));
|
||||
AddAction("/guide", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => channelDevice?.Guide(b)));
|
||||
AddAction("/info", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => channelDevice?.Info(b)));
|
||||
AddAction("/exit", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => channelDevice?.Exit(b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
public class IColorMessenger : MessengerBase
|
||||
{
|
||||
private readonly IColor colorDevice;
|
||||
public IColorMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
colorDevice = device as IColor;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/red", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => colorDevice?.Red(b)));
|
||||
AddAction("/green", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => colorDevice?.Green(b)));
|
||||
AddAction("/yellow", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => colorDevice?.Yellow(b)));
|
||||
AddAction("/blue", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => colorDevice?.Blue(b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
public class IDPadMessenger : MessengerBase
|
||||
{
|
||||
private readonly IDPad dpadDevice;
|
||||
public IDPadMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
dpadDevice = device as IDPad;
|
||||
}
|
||||
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/up", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => dpadDevice?.Up(b)));
|
||||
AddAction("/down", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => dpadDevice?.Down(b)));
|
||||
AddAction("/left", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => dpadDevice?.Left(b)));
|
||||
AddAction("/right", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => dpadDevice?.Right(b)));
|
||||
AddAction("/select", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => dpadDevice?.Select(b)));
|
||||
AddAction("/menu", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => dpadDevice?.Menu(b)));
|
||||
AddAction("/exit", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => dpadDevice?.Exit(b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
public class IDvrMessenger : MessengerBase
|
||||
{
|
||||
private readonly IDvr dvrDevice;
|
||||
public IDvrMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
dvrDevice = device as IDvr;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/dvrlist", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => dvrDevice?.DvrList(b)));
|
||||
AddAction("/record", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => dvrDevice?.Record(b)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
public class IHasPowerMessenger : MessengerBase
|
||||
{
|
||||
private readonly IHasPowerControl powerDevice;
|
||||
public IHasPowerMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
powerDevice = device as IHasPowerControl;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/powerOn", (id, content) => powerDevice?.PowerOn());
|
||||
AddAction("/powerOff", (id, content) => powerDevice?.PowerOff());
|
||||
AddAction("/powerToggle", (id, content) => powerDevice?.PowerToggle());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
public class INumericKeypadMessenger : MessengerBase
|
||||
{
|
||||
private readonly INumericKeypad keypadDevice;
|
||||
public INumericKeypadMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
keypadDevice = device as INumericKeypad;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/num0", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.Digit0(b)));
|
||||
AddAction("/num1", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.Digit1(b)));
|
||||
AddAction("/num2", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.Digit2(b)));
|
||||
AddAction("/num3", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.Digit3(b)));
|
||||
AddAction("/num4", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.Digit4(b)));
|
||||
AddAction("/num5", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.Digit5(b)));
|
||||
AddAction("/num6", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.Digit6(b)));
|
||||
AddAction("/num7", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.Digit7(b)));
|
||||
AddAction("/num8", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.Digit8(b)));
|
||||
AddAction("/num9", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.Digit9(b)));
|
||||
AddAction("/numDash", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.KeypadAccessoryButton1(b)));
|
||||
AddAction("/numEnter", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => keypadDevice?.KeypadAccessoryButton2(b)));
|
||||
// Deal with the Accessory functions on the numpad later
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
public class ISetTopBoxControlsMessenger : MessengerBase
|
||||
{
|
||||
private readonly ISetTopBoxControls stbDevice;
|
||||
public ISetTopBoxControlsMessenger(string key, string messagePath, IKeyName device) : base(key, messagePath, device)
|
||||
{
|
||||
stbDevice = device as ISetTopBoxControls;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
AddAction("/fullStatus", (id, content) => SendISetTopBoxControlsFullMessageObject());
|
||||
AddAction("/dvrList", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => stbDevice?.DvrList(b)));
|
||||
AddAction("/replay", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => stbDevice?.Replay(b)));
|
||||
}
|
||||
/// <summary>
|
||||
/// Helper method to build call status for vtc
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private void SendISetTopBoxControlsFullMessageObject()
|
||||
{
|
||||
|
||||
PostStatusMessage(new SetTopBoxControlsState());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class SetTopBoxControlsState : DeviceStateMessageBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
public class ITransportMessenger : MessengerBase
|
||||
{
|
||||
private readonly ITransport transportDevice;
|
||||
public ITransportMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
transportDevice = device as ITransport;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/play", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => transportDevice?.Play(b)));
|
||||
AddAction("/pause", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => transportDevice?.Pause(b)));
|
||||
AddAction("/stop", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => transportDevice?.Stop(b)));
|
||||
AddAction("/prevTrack", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => transportDevice?.ChapPlus(b)));
|
||||
AddAction("/nextTrack", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => transportDevice?.ChapMinus(b)));
|
||||
AddAction("/rewind", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => transportDevice?.Rewind(b)));
|
||||
AddAction("/ffwd", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => transportDevice?.FFwd(b)));
|
||||
AddAction("/record", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => transportDevice?.Record(b)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a messaging bridge for an AudioCodecBase device
|
||||
/// </summary>
|
||||
public class AudioCodecBaseMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Device being bridged
|
||||
/// </summary>
|
||||
public AudioCodecBase Codec { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constuctor
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="codec"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
public AudioCodecBaseMessenger(string key, AudioCodecBase codec, string messagePath)
|
||||
: base(key, messagePath, codec)
|
||||
{
|
||||
Codec = codec ?? throw new ArgumentNullException("codec");
|
||||
codec.CallStatusChange += Codec_CallStatusChange;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendAtcFullMessageObject());
|
||||
AddAction("/dial", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
Codec.Dial(msg.Value);
|
||||
});
|
||||
|
||||
AddAction("/endCallById", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var call = GetCallWithId(msg.Value);
|
||||
if (call != null)
|
||||
Codec.EndCall(call);
|
||||
});
|
||||
|
||||
AddAction("/endAllCalls", (id, content) => Codec.EndAllCalls());
|
||||
AddAction("/dtmf", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
Codec.SendDtmf(msg.Value);
|
||||
});
|
||||
|
||||
AddAction("/rejectById", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var call = GetCallWithId(msg.Value);
|
||||
|
||||
if (call != null)
|
||||
Codec.RejectCall(call);
|
||||
});
|
||||
|
||||
AddAction("/acceptById", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
var call = GetCallWithId(msg.Value);
|
||||
if (call != null)
|
||||
Codec.AcceptCall(call);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to grab a call with string ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
private CodecActiveCallItem GetCallWithId(string id)
|
||||
{
|
||||
return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
|
||||
}
|
||||
|
||||
private void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
|
||||
{
|
||||
SendAtcFullMessageObject();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to build call status for vtc
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private void SendAtcFullMessageObject()
|
||||
{
|
||||
var info = Codec.CodecInfo;
|
||||
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
isInCall = Codec.IsInCall,
|
||||
calls = Codec.ActiveCalls,
|
||||
info = new
|
||||
{
|
||||
phoneNumber = info.PhoneNumber
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class CameraBaseMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Device being bridged
|
||||
/// </summary>
|
||||
public CameraBase Camera { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="camera"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
public CameraBaseMessenger(string key, CameraBase camera, string messagePath)
|
||||
: base(key, messagePath, camera)
|
||||
{
|
||||
Camera = camera ?? throw new ArgumentNullException("camera");
|
||||
|
||||
|
||||
if (Camera is IHasCameraPresets presetsCamera)
|
||||
{
|
||||
presetsCamera.PresetsListHasChanged += PresetsCamera_PresetsListHasChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void PresetsCamera_PresetsListHasChanged(object sender, EventArgs e)
|
||||
{
|
||||
var presetList = new List<CameraPreset>();
|
||||
|
||||
if (Camera is IHasCameraPresets presetsCamera)
|
||||
presetList = presetsCamera.Presets;
|
||||
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
presets = presetList
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject());
|
||||
|
||||
|
||||
if (Camera is IHasCameraPtzControl ptzCamera)
|
||||
{
|
||||
// Need to evaluate how to pass through these P&H actions. Need a method that takes a bool maybe?
|
||||
AddAction("/cameraUp", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
ptzCamera.TiltUp();
|
||||
return;
|
||||
}
|
||||
|
||||
ptzCamera.TiltStop();
|
||||
}));
|
||||
AddAction("/cameraDown", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
ptzCamera.TiltDown();
|
||||
return;
|
||||
}
|
||||
|
||||
ptzCamera.TiltStop();
|
||||
}));
|
||||
AddAction("/cameraLeft", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
ptzCamera.PanLeft();
|
||||
return;
|
||||
}
|
||||
|
||||
ptzCamera.PanStop();
|
||||
}));
|
||||
AddAction("/cameraRight", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
ptzCamera.PanRight();
|
||||
return;
|
||||
}
|
||||
|
||||
ptzCamera.PanStop();
|
||||
}));
|
||||
AddAction("/cameraZoomIn", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
ptzCamera.ZoomIn();
|
||||
return;
|
||||
}
|
||||
|
||||
ptzCamera.ZoomStop();
|
||||
}));
|
||||
AddAction("/cameraZoomOut", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
ptzCamera.ZoomOut();
|
||||
return;
|
||||
}
|
||||
|
||||
ptzCamera.ZoomStop();
|
||||
}));
|
||||
}
|
||||
|
||||
if (Camera is IHasCameraAutoMode)
|
||||
{
|
||||
AddAction("/cameraModeAuto", (id, content) => (Camera as IHasCameraAutoMode).CameraAutoModeOn());
|
||||
|
||||
AddAction("/cameraModeManual", (id, content) => (Camera as IHasCameraAutoMode).CameraAutoModeOff());
|
||||
|
||||
}
|
||||
|
||||
if (Camera is IHasPowerControl)
|
||||
{
|
||||
AddAction("/cameraModeOff", (id, content) => (Camera as IHasPowerControl).PowerOff());
|
||||
AddAction("/cameraModeManual", (id, content) => (Camera as IHasPowerControl).PowerOn());
|
||||
}
|
||||
|
||||
|
||||
if (Camera is IHasCameraPresets presetsCamera)
|
||||
{
|
||||
for (int i = 1; i <= 6; i++)
|
||||
{
|
||||
var preset = i;
|
||||
AddAction("/cameraPreset" + i, (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<int>>();
|
||||
|
||||
presetsCamera.PresetSelect(msg.Value);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleCameraPressAndHold(JToken content, Action<bool> cameraAction)
|
||||
{
|
||||
var state = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value);
|
||||
if (timerHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
timerHandler(state.Value, cameraAction);
|
||||
|
||||
cameraAction(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to update the full status of the camera
|
||||
/// </summary>
|
||||
private void SendCameraFullMessageObject()
|
||||
{
|
||||
var presetList = new List<CameraPreset>();
|
||||
|
||||
if (Camera is IHasCameraPresets presetsCamera)
|
||||
presetList = presetsCamera.Presets;
|
||||
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
cameraManualSupported = Camera is IHasCameraControls,
|
||||
cameraAutoSupported = Camera is IHasCameraAutoMode,
|
||||
cameraOffSupported = Camera is IHasCameraOff,
|
||||
cameraMode = GetCameraMode(),
|
||||
hasPresets = Camera is IHasCameraPresets,
|
||||
presets = presetList
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the current camera mode
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string GetCameraMode()
|
||||
{
|
||||
string m;
|
||||
if (Camera is IHasCameraAutoMode && (Camera as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.BoolValue)
|
||||
m = eCameraControlMode.Auto.ToString().ToLower();
|
||||
else if (Camera is IHasPowerControlWithFeedback && !(Camera as IHasPowerControlWithFeedback).PowerIsOnFeedback.BoolValue)
|
||||
m = eCameraControlMode.Off.ToString().ToLower();
|
||||
else
|
||||
m = eCameraControlMode.Manual.ToString().ToLower();
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceInfo;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class DeviceInfoMessenger : MessengerBase
|
||||
{
|
||||
private readonly IDeviceInfoProvider _deviceInfoProvider;
|
||||
public DeviceInfoMessenger(string key, string messagePath, IDeviceInfoProvider device) : base(key, messagePath, device as Device)
|
||||
{
|
||||
_deviceInfoProvider = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
_deviceInfoProvider.DeviceInfoChanged += (o, a) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
deviceInfo = a.DeviceInfo
|
||||
}));
|
||||
};
|
||||
|
||||
AddAction("/fullStatus", (id, context) => PostStatusMessage(new DeviceInfoStateMessage
|
||||
{
|
||||
DeviceInfo = _deviceInfoProvider.DeviceInfo
|
||||
}));
|
||||
|
||||
AddAction("/update", (id, context) => _deviceInfoProvider.UpdateDeviceInfo());
|
||||
}
|
||||
}
|
||||
|
||||
public class DeviceInfoStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("deviceInfo")]
|
||||
public DeviceInfo DeviceInfo { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class DevicePresetsModelMessenger : MessengerBase
|
||||
{
|
||||
private readonly ITvPresetsProvider _presetsDevice;
|
||||
|
||||
public DevicePresetsModelMessenger(string key, string messagePath, ITvPresetsProvider presetsDevice)
|
||||
: base(key, messagePath, presetsDevice as Device)
|
||||
{
|
||||
_presetsDevice = presetsDevice;
|
||||
}
|
||||
|
||||
private void SendPresets()
|
||||
{
|
||||
PostStatusMessage(new PresetStateMessage
|
||||
{
|
||||
Favorites = _presetsDevice.TvPresets.PresetsList
|
||||
});
|
||||
}
|
||||
|
||||
private void RecallPreset(ISetTopBoxNumericKeypad device, string channel)
|
||||
{
|
||||
_presetsDevice.TvPresets.Dial(channel, device);
|
||||
}
|
||||
|
||||
private void SavePresets(List<PresetChannel> presets)
|
||||
{
|
||||
_presetsDevice.TvPresets.UpdatePresets(presets);
|
||||
}
|
||||
|
||||
|
||||
#region Overrides of MessengerBase
|
||||
|
||||
protected override void RegisterActions()
|
||||
|
||||
{
|
||||
AddAction("/presets/fullStatus", (id, content) =>
|
||||
{
|
||||
this.LogInformation("getting full status for client {id}", id);
|
||||
try
|
||||
{
|
||||
SendPresets();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception sending preset full status", this);
|
||||
}
|
||||
});
|
||||
|
||||
AddAction("/presets/recall", (id, content) =>
|
||||
{
|
||||
var p = content.ToObject<PresetChannelMessage>();
|
||||
|
||||
|
||||
if (!(DeviceManager.GetDeviceForKey(p.DeviceKey) is ISetTopBoxNumericKeypad dev))
|
||||
{
|
||||
this.LogDebug("Unable to find device with key {0}", p.DeviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
RecallPreset(dev, p.Preset.Channel);
|
||||
});
|
||||
|
||||
AddAction("/presets/save", (id, content) =>
|
||||
{
|
||||
var presets = content.ToObject<List<PresetChannel>>();
|
||||
|
||||
SavePresets(presets);
|
||||
});
|
||||
|
||||
_presetsDevice.TvPresets.PresetsSaved += (p) => SendPresets();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class PresetChannelMessage
|
||||
{
|
||||
[JsonProperty("preset")]
|
||||
public PresetChannel Preset;
|
||||
|
||||
[JsonProperty("deviceKey")]
|
||||
public string DeviceKey;
|
||||
}
|
||||
|
||||
public class PresetStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("favorites", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<PresetChannel> Favorites { get; set; } = new List<PresetChannel>();
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class DeviceVolumeMessenger : MessengerBase
|
||||
{
|
||||
private readonly IBasicVolumeWithFeedback _localDevice;
|
||||
|
||||
public DeviceVolumeMessenger(string key, string messagePath, IBasicVolumeWithFeedback device)
|
||||
: base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
_localDevice = device;
|
||||
}
|
||||
|
||||
private void SendStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
var messageObj = new VolumeStateMessage
|
||||
{
|
||||
Volume = new Volume
|
||||
{
|
||||
Level = _localDevice?.VolumeLevelFeedback.IntValue ?? -1,
|
||||
Muted = _localDevice?.MuteFeedback.BoolValue ?? false,
|
||||
HasMute = true, // assume all devices have mute for now
|
||||
}
|
||||
};
|
||||
|
||||
if (_localDevice is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
|
||||
{
|
||||
messageObj.Volume.RawValue = volumeAdvanced.RawVolumeLevel.ToString();
|
||||
messageObj.Volume.Units = volumeAdvanced.Units;
|
||||
}
|
||||
|
||||
PostStatusMessage(messageObj);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception sending full status", this);
|
||||
}
|
||||
}
|
||||
|
||||
#region Overrides of MessengerBase
|
||||
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendStatus());
|
||||
|
||||
AddAction("/level", (id, content) =>
|
||||
{
|
||||
var volume = content.ToObject<MobileControlSimpleContent<ushort>>();
|
||||
|
||||
_localDevice.SetVolume(volume.Value);
|
||||
});
|
||||
|
||||
AddAction("/muteToggle", (id, content) =>
|
||||
{
|
||||
_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) =>
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Calling {localDevice} volume down with {value}", DeviceKey, b);
|
||||
|
||||
try
|
||||
{
|
||||
_localDevice.VolumeDown(b);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Got exception during volume down: {Exception}", null, ex);
|
||||
}
|
||||
}));
|
||||
|
||||
_localDevice.MuteFeedback.OutputChange += (sender, args) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(
|
||||
new
|
||||
{
|
||||
volume = new
|
||||
{
|
||||
muted = args.BoolValue
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
_localDevice.VolumeLevelFeedback.OutputChange += (sender, args) =>
|
||||
{
|
||||
var rawValue = "";
|
||||
if (_localDevice is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
|
||||
{
|
||||
rawValue = volumeAdvanced.RawVolumeLevel.ToString();
|
||||
}
|
||||
|
||||
var message = new
|
||||
{
|
||||
volume = new
|
||||
{
|
||||
level = args.IntValue,
|
||||
rawValue
|
||||
}
|
||||
};
|
||||
|
||||
PostStatusMessage(JToken.FromObject(message));
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class VolumeStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("volume", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Volume Volume { get; set; }
|
||||
}
|
||||
|
||||
public class Volume
|
||||
{
|
||||
[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? Level { get; set; }
|
||||
|
||||
[JsonProperty("hasMute", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasMute { get; set; }
|
||||
|
||||
[JsonProperty("muted", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? Muted { get; set; }
|
||||
|
||||
[JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Label { get; set; }
|
||||
|
||||
[JsonProperty("rawValue", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string RawValue { get; set; }
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonProperty("units", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public eVolumeLevelUnits? Units { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class GenericMessenger : MessengerBase
|
||||
{
|
||||
public GenericMessenger(string key, EssentialsDevice device, string messagePath) : base(key, messagePath, device)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new DeviceStateMessageBase();
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class ICommunicationMonitorMessenger : MessengerBase
|
||||
{
|
||||
private readonly ICommunicationMonitor _communicationMonitor;
|
||||
|
||||
public ICommunicationMonitorMessenger(string key, string messagePath, ICommunicationMonitor device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
_communicationMonitor = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) =>
|
||||
{
|
||||
PostStatusMessage(new CommunicationMonitorState
|
||||
{
|
||||
CommunicationMonitor = new CommunicationMonitorProps
|
||||
{
|
||||
IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline,
|
||||
Status = _communicationMonitor.CommunicationMonitor.Status
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
_communicationMonitor.CommunicationMonitor.StatusChange += (sender, args) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
commMonitor = new CommunicationMonitorProps
|
||||
{
|
||||
IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline,
|
||||
Status = _communicationMonitor.CommunicationMonitor.Status
|
||||
}
|
||||
}));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the state of the communication monitor
|
||||
/// </summary>
|
||||
public class CommunicationMonitorState : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("commMonitor", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CommunicationMonitorProps CommunicationMonitor { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class CommunicationMonitorProps
|
||||
{ /// <summary>
|
||||
/// For devices that implement ICommunicationMonitor, reports the online status of the device
|
||||
/// </summary>
|
||||
[JsonProperty("isOnline", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsOnline { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// For devices that implement ICommunicationMonitor, reports the online status of the device
|
||||
/// </summary>
|
||||
[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public MonitorStatus Status { get; set; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class IDspPresetsMessenger : MessengerBase
|
||||
{
|
||||
private readonly IDspPresets device;
|
||||
|
||||
public IDspPresetsMessenger(string key, string messagePath, IDspPresets device)
|
||||
: base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) =>
|
||||
{
|
||||
var message = new IHasDspPresetsStateMessage
|
||||
{
|
||||
Presets = device.Presets
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
});
|
||||
|
||||
AddAction("/recallPreset", (id, content) =>
|
||||
{
|
||||
var presetKey = content.ToObject<string>();
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(presetKey))
|
||||
{
|
||||
device.RecallPreset(presetKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class IHasDspPresetsStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("presets")]
|
||||
public Dictionary<string, IKeyName> Presets { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class IEssentialsRoomCombinerMessenger : MessengerBase
|
||||
{
|
||||
private readonly IEssentialsRoomCombiner _roomCombiner;
|
||||
|
||||
public IEssentialsRoomCombinerMessenger(string key, string messagePath, IEssentialsRoomCombiner roomCombiner)
|
||||
: base(key, messagePath, roomCombiner as Device)
|
||||
{
|
||||
_roomCombiner = roomCombiner;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/setAutoMode", (id, content) =>
|
||||
{
|
||||
_roomCombiner.SetAutoMode();
|
||||
});
|
||||
|
||||
AddAction("/setManualMode", (id, content) =>
|
||||
{
|
||||
_roomCombiner.SetManualMode();
|
||||
});
|
||||
|
||||
AddAction("/toggleMode", (id, content) =>
|
||||
{
|
||||
_roomCombiner.ToggleMode();
|
||||
});
|
||||
|
||||
AddAction("/togglePartitionState", (id, content) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var partitionKey = content.ToObject<string>();
|
||||
|
||||
_roomCombiner.TogglePartitionState(partitionKey);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, $"Error toggling partition state: {e}", this);
|
||||
}
|
||||
});
|
||||
|
||||
AddAction("/setRoomCombinationScenario", (id, content) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var scenarioKey = content.ToObject<string>();
|
||||
|
||||
_roomCombiner.SetRoomCombinationScenario(scenarioKey);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, $"Error toggling partition state: {e}", this);
|
||||
}
|
||||
});
|
||||
|
||||
_roomCombiner.RoomCombinationScenarioChanged += (sender, args) =>
|
||||
{
|
||||
SendFullStatus();
|
||||
};
|
||||
|
||||
_roomCombiner.IsInAutoModeFeedback.OutputChange += (sender, args) =>
|
||||
{
|
||||
var message = new
|
||||
{
|
||||
isInAutoMode = _roomCombiner.IsInAutoModeFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(JToken.FromObject(message));
|
||||
};
|
||||
|
||||
foreach (var partition in _roomCombiner.Partitions)
|
||||
{
|
||||
partition.PartitionPresentFeedback.OutputChange += (sender, args) =>
|
||||
{
|
||||
var message = new
|
||||
{
|
||||
partitions = _roomCombiner.Partitions
|
||||
};
|
||||
|
||||
PostStatusMessage(JToken.FromObject(message));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
var rooms = new List<IKeyName>();
|
||||
|
||||
foreach (var room in _roomCombiner.Rooms)
|
||||
{
|
||||
rooms.Add(new RoomCombinerRoom { Key = room.Key, Name = room.Name });
|
||||
}
|
||||
|
||||
var message = new IEssentialsRoomCombinerStateMessage
|
||||
{
|
||||
IsInAutoMode = _roomCombiner.IsInAutoMode,
|
||||
CurrentScenario = _roomCombiner.CurrentScenario,
|
||||
Rooms = rooms,
|
||||
RoomCombinationScenarios = _roomCombiner.RoomCombinationScenarios,
|
||||
Partitions = _roomCombiner.Partitions
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.LogException(e, "Error sending full status");
|
||||
}
|
||||
}
|
||||
|
||||
private class RoomCombinerRoom : IKeyName
|
||||
{
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
public class IEssentialsRoomCombinerStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("isInAutoMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool IsInAutoMode { get; set; }
|
||||
|
||||
[JsonProperty("currentScenario", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public IRoomCombinationScenario CurrentScenario { get; set; }
|
||||
|
||||
[JsonProperty("rooms", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<IKeyName> Rooms { get; set; }
|
||||
|
||||
[JsonProperty("roomCombinationScenarios", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<IRoomCombinationScenario> RoomCombinationScenarios { get; set; }
|
||||
|
||||
[JsonProperty("partitions", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<IPartitionController> Partitions { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class IHasCurrentSourceInfoMessenger : MessengerBase
|
||||
{
|
||||
private readonly IHasCurrentSourceInfoChange sourceDevice;
|
||||
public IHasCurrentSourceInfoMessenger(string key, string messagePath, IHasCurrentSourceInfoChange device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
sourceDevice = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) =>
|
||||
{
|
||||
var message = new CurrentSourceStateMessage
|
||||
{
|
||||
CurrentSourceKey = sourceDevice.CurrentSourceInfoKey,
|
||||
CurrentSource = sourceDevice.CurrentSourceInfo
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
});
|
||||
|
||||
sourceDevice.CurrentSourceChange += (sender, e) =>
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case ChangeType.DidChange:
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
currentSourceKey = string.IsNullOrEmpty(sourceDevice.CurrentSourceInfoKey) ? string.Empty : sourceDevice.CurrentSourceInfoKey,
|
||||
currentSource = sourceDevice.CurrentSourceInfo
|
||||
}));
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class CurrentSourceStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("currentSourceKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CurrentSourceKey { get; set; }
|
||||
|
||||
[JsonProperty("currentSource")]
|
||||
public SourceListItem CurrentSource { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class IHasPowerControlWithFeedbackMessenger : MessengerBase
|
||||
{
|
||||
private readonly IHasPowerControlWithFeedback _powerControl;
|
||||
|
||||
public IHasPowerControlWithFeedbackMessenger(string key, string messagePath, IHasPowerControlWithFeedback powerControl)
|
||||
: base(key, messagePath, powerControl as Device)
|
||||
{
|
||||
_powerControl = powerControl;
|
||||
}
|
||||
|
||||
public void SendFullStatus()
|
||||
{
|
||||
var messageObj = new PowerControlWithFeedbackStateMessage
|
||||
{
|
||||
PowerState = _powerControl.PowerIsOnFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(messageObj);
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
_powerControl.PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange; ;
|
||||
}
|
||||
|
||||
private void PowerIsOnFeedback_OutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
powerState = args.BoolValue
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public class PowerControlWithFeedbackStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("powerState", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? PowerState { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class IHasScheduleAwarenessMessenger : MessengerBase
|
||||
{
|
||||
public IHasScheduleAwareness ScheduleSource { get; private set; }
|
||||
|
||||
public IHasScheduleAwarenessMessenger(string key, IHasScheduleAwareness scheduleSource, string messagePath)
|
||||
: base(key, messagePath, scheduleSource as Device)
|
||||
{
|
||||
ScheduleSource = scheduleSource ?? throw new ArgumentNullException("scheduleSource");
|
||||
ScheduleSource.CodecSchedule.MeetingsListHasChanged += new EventHandler<EventArgs>(CodecSchedule_MeetingsListHasChanged);
|
||||
ScheduleSource.CodecSchedule.MeetingEventChange += new EventHandler<MeetingEventArgs>(CodecSchedule_MeetingEventChange);
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/schedule/fullStatus", (id, content) => SendFullScheduleObject());
|
||||
}
|
||||
|
||||
private void CodecSchedule_MeetingEventChange(object sender, MeetingEventArgs e)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new MeetingChangeMessage
|
||||
{
|
||||
MeetingChange = new MeetingChange
|
||||
{
|
||||
ChangeType = e.ChangeType.ToString(),
|
||||
Meeting = e.Meeting
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private void CodecSchedule_MeetingsListHasChanged(object sender, EventArgs e)
|
||||
{
|
||||
SendFullScheduleObject();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to send the full schedule data
|
||||
/// </summary>
|
||||
private void SendFullScheduleObject()
|
||||
{
|
||||
PostStatusMessage(new FullScheduleMessage
|
||||
{
|
||||
Meetings = ScheduleSource.CodecSchedule.Meetings,
|
||||
MeetingWarningMinutes = ScheduleSource.CodecSchedule.MeetingWarningMinutes
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class FullScheduleMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("meetings", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<Meeting> Meetings { get; set; }
|
||||
|
||||
[JsonProperty("meetingWarningMinutes", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int MeetingWarningMinutes { get; set; }
|
||||
}
|
||||
|
||||
public class MeetingChangeMessage
|
||||
{
|
||||
[JsonProperty("meetingChange", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public MeetingChange MeetingChange { get; set; }
|
||||
}
|
||||
|
||||
public class MeetingChange
|
||||
{
|
||||
[JsonProperty("changeType", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string ChangeType { get; set; }
|
||||
|
||||
[JsonProperty("meeting", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Meeting Meeting { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class IHumiditySensorMessenger : MessengerBase
|
||||
{
|
||||
private readonly IHumiditySensor device;
|
||||
|
||||
public IHumiditySensorMessenger(string key, IHumiditySensor device, string messagePath)
|
||||
: base(key, messagePath, device as Device)
|
||||
{
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
device.HumidityFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new IHumiditySensorStateMessage
|
||||
{
|
||||
Humidity = string.Format("{0}%", device.HumidityFeedback.UShortValue)
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
public class IHumiditySensorStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("humidity")]
|
||||
public string Humidity { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class ILevelControlsMessenger : MessengerBase
|
||||
{
|
||||
private ILevelControls levelControlsDevice;
|
||||
public ILevelControlsMessenger(string key, string messagePath, ILevelControls device) : base(key, messagePath, device as Device)
|
||||
{
|
||||
levelControlsDevice = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
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 })
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
});
|
||||
|
||||
foreach (var levelControl in levelControlsDevice.LevelControlPoints)
|
||||
{
|
||||
// reassigning here just in case of lambda closure issues
|
||||
var key = levelControl.Key;
|
||||
var control = levelControl.Value;
|
||||
|
||||
AddAction($"/{key}/level", (id, content) =>
|
||||
{
|
||||
var request = content.ToObject<MobileControlSimpleContent<ushort>>();
|
||||
|
||||
control.SetVolume(request.Value);
|
||||
});
|
||||
|
||||
AddAction($"/{key}/muteToggle", (id, content) =>
|
||||
{
|
||||
control.MuteToggle();
|
||||
});
|
||||
|
||||
AddAction($"/{key}/muteOn", (id, content) => control.MuteOn());
|
||||
|
||||
AddAction($"/{key}/muteOff", (id, content) => control.MuteOff());
|
||||
|
||||
AddAction($"/{key}/volumeUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => control.VolumeUp(b)));
|
||||
|
||||
AddAction($"/{key}/volumeDown", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => control.VolumeDown(b)));
|
||||
|
||||
control.VolumeLevelFeedback.OutputChange += (o, a) => PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
levelControls = new Dictionary<string, Volume>
|
||||
{
|
||||
{key, new Volume{Level = a.IntValue} }
|
||||
}
|
||||
}));
|
||||
|
||||
control.MuteFeedback.OutputChange += (o, a) => PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
levelControls = new Dictionary<string, Volume>
|
||||
{
|
||||
{key, new Volume{Muted = a.BoolValue} }
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LevelControlStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("levelControls")]
|
||||
public Dictionary<string, Volume> Levels { get; set; }
|
||||
}
|
||||
|
||||
public class LevelControlRequestMessage
|
||||
{
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public ushort? Level { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implment IMatrixRouting
|
||||
/// </summary>
|
||||
public class IMatrixRoutingMessenger : MessengerBase
|
||||
{
|
||||
private readonly IMatrixRouting matrixDevice;
|
||||
public IMatrixRoutingMessenger(string key, string messagePath, IMatrixRouting device) : base(key, messagePath, device as Device)
|
||||
{
|
||||
matrixDevice = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
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)),
|
||||
};
|
||||
|
||||
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(e, "Exception Getting full status: {@exception}", this, e);
|
||||
}
|
||||
});
|
||||
|
||||
AddAction("/route", (id, content) =>
|
||||
{
|
||||
var request = content.ToObject<MatrixRouteRequest>();
|
||||
|
||||
matrixDevice.Route(request.InputKey, request.OutputKey, request.RouteType);
|
||||
});
|
||||
|
||||
foreach (var output in matrixDevice.OutputSlots)
|
||||
{
|
||||
var key = output.Key;
|
||||
var outputSlot = output.Value;
|
||||
|
||||
outputSlot.OutputSlotChanged += (sender, args) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
outputs = matrixDevice.OutputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingOutput(kvp.Value))
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
foreach (var input in matrixDevice.InputSlots)
|
||||
{
|
||||
var key = input.Key;
|
||||
var inputSlot = input.Value;
|
||||
|
||||
inputSlot.VideoSyncChanged += (sender, args) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
inputs = matrixDevice.InputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingInput(kvp.Value))
|
||||
}));
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MatrixStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("outputs")]
|
||||
public Dictionary<string, RoutingOutput> Outputs;
|
||||
|
||||
[JsonProperty("inputs")]
|
||||
public Dictionary<string, RoutingInput> Inputs;
|
||||
}
|
||||
|
||||
public class RoutingInput
|
||||
{
|
||||
private IRoutingInputSlot _input;
|
||||
|
||||
[JsonProperty("txDeviceKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string TxDeviceKey => _input?.TxDeviceKey;
|
||||
|
||||
[JsonProperty("slotNumber", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? SlotNumber => _input?.SlotNumber;
|
||||
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
[JsonProperty("supportedSignalTypes", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public eRoutingSignalType? SupportedSignalTypes => _input?.SupportedSignalTypes;
|
||||
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Name => _input?.Name;
|
||||
|
||||
[JsonProperty("isOnline", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsOnline => _input?.IsOnline.BoolValue;
|
||||
|
||||
[JsonProperty("videoSyncDetected", NullValueHandling = NullValueHandling.Ignore)]
|
||||
|
||||
public bool? VideoSyncDetected => _input?.VideoSyncDetected;
|
||||
|
||||
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Key => _input?.Key;
|
||||
|
||||
public RoutingInput(IRoutingInputSlot input)
|
||||
{
|
||||
_input = input;
|
||||
}
|
||||
}
|
||||
|
||||
public class RoutingOutput
|
||||
{
|
||||
private IRoutingOutputSlot _output;
|
||||
|
||||
|
||||
public RoutingOutput(IRoutingOutputSlot output)
|
||||
{
|
||||
_output = output;
|
||||
}
|
||||
|
||||
[JsonProperty("rxDeviceKey")]
|
||||
public string RxDeviceKey => _output.RxDeviceKey;
|
||||
|
||||
[JsonProperty("currentRoutes")]
|
||||
public Dictionary<string, RoutingInput> CurrentRoutes => _output.CurrentRoutes.ToDictionary(kvp => kvp.Key.ToString(), kvp => new RoutingInput(kvp.Value));
|
||||
|
||||
[JsonProperty("slotNumber")]
|
||||
public int SlotNumber => _output.SlotNumber;
|
||||
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
[JsonProperty("supportedSignalTypes")]
|
||||
public eRoutingSignalType SupportedSignalTypes => _output.SupportedSignalTypes;
|
||||
|
||||
[JsonProperty("name")]
|
||||
public string Name => _output.Name;
|
||||
|
||||
[JsonProperty("key")]
|
||||
public string Key => _output.Key;
|
||||
}
|
||||
|
||||
public class MatrixRouteRequest
|
||||
{
|
||||
[JsonProperty("outputKey")]
|
||||
public string OutputKey { get; set; }
|
||||
|
||||
[JsonProperty("inputKey")]
|
||||
public string InputKey { get; set; }
|
||||
|
||||
[JsonProperty("routeType")]
|
||||
public eRoutingSignalType RouteType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class IProjectorScreenLiftControlMessenger : MessengerBase
|
||||
{
|
||||
private readonly IProjectorScreenLiftControl device;
|
||||
|
||||
public IProjectorScreenLiftControlMessenger(string key, string messagePath, IProjectorScreenLiftControl screenLiftDevice)
|
||||
: base(key, messagePath, screenLiftDevice as Device)
|
||||
{
|
||||
device = screenLiftDevice;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/raise", (id, content) =>
|
||||
{
|
||||
|
||||
device.Raise();
|
||||
|
||||
});
|
||||
|
||||
AddAction("/lower", (id, content) =>
|
||||
{
|
||||
|
||||
device.Lower();
|
||||
|
||||
});
|
||||
|
||||
device.PositionChanged += Device_PositionChanged;
|
||||
|
||||
}
|
||||
|
||||
private void Device_PositionChanged(object sender, EventArgs e)
|
||||
{
|
||||
var state = new
|
||||
{
|
||||
inUpPosition = device.InUpPosition
|
||||
};
|
||||
PostStatusMessage(JToken.FromObject(state));
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new ScreenLiftStateMessage
|
||||
{
|
||||
InUpPosition = device.InUpPosition,
|
||||
Type = device.Type,
|
||||
DisplayDeviceKey = device.DisplayDeviceKey
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
public class ScreenLiftStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("inUpPosition", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? InUpPosition { get; set; }
|
||||
|
||||
[JsonProperty("displayDeviceKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string DisplayDeviceKey { get; set; }
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public eScreenLiftControlType Type { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class RunRouteActionMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Device being bridged
|
||||
/// </summary>
|
||||
public IRunRouteAction RoutingDevice { get; private set; }
|
||||
|
||||
public RunRouteActionMessenger(string key, IRunRouteAction routingDevice, string messagePath)
|
||||
: base(key, messagePath, routingDevice as Device)
|
||||
{
|
||||
RoutingDevice = routingDevice ?? throw new ArgumentNullException("routingDevice");
|
||||
|
||||
|
||||
if (RoutingDevice is IRoutingSink routingSink)
|
||||
{
|
||||
routingSink.CurrentSourceChange += RoutingSink_CurrentSourceChange;
|
||||
}
|
||||
}
|
||||
|
||||
private void RoutingSink_CurrentSourceChange(SourceListItem info, ChangeType type)
|
||||
{
|
||||
SendRoutingFullMessageObject();
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject());
|
||||
|
||||
AddAction("/source", (id, content) =>
|
||||
{
|
||||
var c = content.ToObject<SourceSelectMessageContent>();
|
||||
// assume no sourceListKey
|
||||
var sourceListKey = string.Empty;
|
||||
|
||||
if (!string.IsNullOrEmpty(c.SourceListKey))
|
||||
{
|
||||
// Check for source list in content of message
|
||||
sourceListKey = c.SourceListKey;
|
||||
}
|
||||
|
||||
RoutingDevice.RunRouteAction(c.SourceListItemKey, sourceListKey);
|
||||
});
|
||||
|
||||
if (RoutingDevice is IRoutingSink sinkDevice)
|
||||
{
|
||||
sinkDevice.CurrentSourceChange += (o, a) => SendRoutingFullMessageObject();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to update full status of the routing device
|
||||
/// </summary>
|
||||
private void SendRoutingFullMessageObject()
|
||||
{
|
||||
if (RoutingDevice is IRoutingSink sinkDevice)
|
||||
{
|
||||
var sourceKey = sinkDevice.CurrentSourceInfoKey;
|
||||
|
||||
if (string.IsNullOrEmpty(sourceKey))
|
||||
sourceKey = "none";
|
||||
|
||||
PostStatusMessage(new RoutingStateMessage
|
||||
{
|
||||
SelectedSourceKey = sourceKey
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RoutingStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("selectedSourceKey")]
|
||||
public string SelectedSourceKey { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class ISelectableItemsMessenger<TKey> : MessengerBase
|
||||
{
|
||||
private static readonly JsonSerializer serializer = new JsonSerializer { Converters = { new StringEnumConverter() } };
|
||||
private ISelectableItems<TKey> itemDevice;
|
||||
|
||||
private readonly string _propName;
|
||||
public ISelectableItemsMessenger(string key, string messagePath, ISelectableItems<TKey> device, string propName) : base(key, messagePath, device as Device)
|
||||
{
|
||||
itemDevice = device;
|
||||
_propName = propName;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, context) =>
|
||||
{
|
||||
SendFullStatus();
|
||||
});
|
||||
|
||||
itemDevice.ItemsUpdated += (sender, args) =>
|
||||
{
|
||||
SendFullStatus();
|
||||
};
|
||||
|
||||
itemDevice.CurrentItemChanged += (sender, args) =>
|
||||
{
|
||||
SendFullStatus();
|
||||
};
|
||||
|
||||
foreach (var input in itemDevice.Items)
|
||||
{
|
||||
var key = input.Key;
|
||||
var localItem = input.Value;
|
||||
|
||||
AddAction($"/{key}", (id, content) =>
|
||||
{
|
||||
localItem.Select();
|
||||
});
|
||||
|
||||
localItem.ItemUpdated += (sender, args) =>
|
||||
{
|
||||
SendFullStatus();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var stateObject = new JObject();
|
||||
stateObject[_propName] = JToken.FromObject(itemDevice, serializer);
|
||||
PostStatusMessage(stateObject);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class IShutdownPromptTimerMessenger : MessengerBase
|
||||
{
|
||||
private readonly IShutdownPromptTimer _room;
|
||||
|
||||
public IShutdownPromptTimerMessenger(string key, string messagePath, IShutdownPromptTimer room)
|
||||
: base(key, messagePath, room as Device)
|
||||
{
|
||||
_room = room;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/status", (id, content) =>
|
||||
{
|
||||
SendFullStatus();
|
||||
});
|
||||
|
||||
AddAction("/setShutdownPromptSeconds", (id, content) =>
|
||||
{
|
||||
var response = content.ToObject<int>();
|
||||
|
||||
_room.SetShutdownPromptSeconds(response);
|
||||
|
||||
SendFullStatus();
|
||||
});
|
||||
|
||||
AddAction("/shutdownStart", (id, content) => _room.StartShutdown(eShutdownType.Manual));
|
||||
|
||||
AddAction("/shutdownEnd", (id, content) => _room.ShutdownPromptTimer.Finish());
|
||||
|
||||
AddAction("/shutdownCancel", (id, content) => _room.ShutdownPromptTimer.Cancel());
|
||||
|
||||
|
||||
_room.ShutdownPromptTimer.HasStarted += (sender, args) =>
|
||||
{
|
||||
PostEventMessage("timerStarted");
|
||||
};
|
||||
|
||||
_room.ShutdownPromptTimer.HasFinished += (sender, args) =>
|
||||
{
|
||||
PostEventMessage("timerFinished");
|
||||
};
|
||||
|
||||
_room.ShutdownPromptTimer.WasCancelled += (sender, args) =>
|
||||
{
|
||||
PostEventMessage("timerCancelled");
|
||||
};
|
||||
|
||||
_room.ShutdownPromptTimer.SecondsRemainingFeedback.OutputChange += (sender, args) =>
|
||||
{
|
||||
var status = new
|
||||
{
|
||||
secondsRemaining = _room.ShutdownPromptTimer.SecondsRemainingFeedback.IntValue,
|
||||
percentageRemaining = _room.ShutdownPromptTimer.PercentFeedback.UShortValue
|
||||
};
|
||||
|
||||
PostStatusMessage(JToken.FromObject(status));
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var status = new IShutdownPromptTimerStateMessage
|
||||
{
|
||||
ShutdownPromptSeconds = _room.ShutdownPromptTimer.SecondsToCount,
|
||||
SecondsRemaining = _room.ShutdownPromptTimer.SecondsRemainingFeedback.IntValue,
|
||||
PercentageRemaining = _room.ShutdownPromptTimer.PercentFeedback.UShortValue
|
||||
};
|
||||
|
||||
PostStatusMessage(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class IShutdownPromptTimerStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("secondsRemaining")]
|
||||
public int SecondsRemaining { get; set; }
|
||||
|
||||
[JsonProperty("percentageRemaining")]
|
||||
public int PercentageRemaining { get; set; }
|
||||
|
||||
[JsonProperty("shutdownPromptSeconds")]
|
||||
public int ShutdownPromptSeconds { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.CrestronIO;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class ISwitchedOutputMessenger : MessengerBase
|
||||
{
|
||||
|
||||
private readonly ISwitchedOutput device;
|
||||
|
||||
public ISwitchedOutputMessenger(string key, ISwitchedOutput device, string messagePath)
|
||||
: base(key, messagePath, device as Device)
|
||||
{
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/on", (id, content) =>
|
||||
{
|
||||
|
||||
device.On();
|
||||
|
||||
});
|
||||
|
||||
AddAction("/off", (id, content) =>
|
||||
{
|
||||
|
||||
device.Off();
|
||||
|
||||
});
|
||||
|
||||
device.OutputIsOnFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new ISwitchedOutputStateMessage
|
||||
{
|
||||
IsOn = device.OutputIsOnFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
public class ISwitchedOutputStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("isOn")]
|
||||
public bool IsOn { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class ITechPasswordMessenger : MessengerBase
|
||||
{
|
||||
private readonly ITechPassword _room;
|
||||
|
||||
public ITechPasswordMessenger(string key, string messagePath, ITechPassword room)
|
||||
: base(key, messagePath, room as Device)
|
||||
{
|
||||
_room = room;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
|
||||
AddAction("/status", (id, content) =>
|
||||
{
|
||||
SendFullStatus();
|
||||
});
|
||||
|
||||
AddAction("/validateTechPassword", (id, content) =>
|
||||
{
|
||||
var password = content.Value<string>("password");
|
||||
|
||||
_room.ValidateTechPassword(password);
|
||||
});
|
||||
|
||||
AddAction("/setTechPassword", (id, content) =>
|
||||
{
|
||||
var response = content.ToObject<SetTechPasswordContent>();
|
||||
|
||||
_room.SetTechPassword(response.OldPassword, response.NewPassword);
|
||||
});
|
||||
|
||||
_room.TechPasswordChanged += (sender, args) =>
|
||||
{
|
||||
PostEventMessage("passwordChangedSuccessfully");
|
||||
};
|
||||
|
||||
_room.TechPasswordValidateResult += (sender, args) =>
|
||||
{
|
||||
var evt = new ITechPasswordEventMessage
|
||||
{
|
||||
IsValid = args.IsValid
|
||||
};
|
||||
|
||||
PostEventMessage(evt, "passwordValidationResult");
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var status = new ITechPasswordStateMessage
|
||||
{
|
||||
TechPasswordLength = _room.TechPasswordLength
|
||||
};
|
||||
|
||||
PostStatusMessage(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ITechPasswordStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("techPasswordLength", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? TechPasswordLength { get; set; }
|
||||
}
|
||||
|
||||
public class ITechPasswordEventMessage : DeviceEventMessageBase
|
||||
{
|
||||
[JsonProperty("isValid", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsValid { get; set; }
|
||||
}
|
||||
|
||||
internal class SetTechPasswordContent
|
||||
{
|
||||
[JsonProperty("oldPassword")]
|
||||
public string OldPassword { get; set; }
|
||||
|
||||
[JsonProperty("newPassword")]
|
||||
public string NewPassword { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class ITemperatureSensorMessenger : MessengerBase
|
||||
{
|
||||
private readonly ITemperatureSensor device;
|
||||
|
||||
public ITemperatureSensorMessenger(string key, ITemperatureSensor device, string messagePath)
|
||||
: base(key, messagePath, device as Device)
|
||||
{
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/setTemperatureUnitsToCelcius", (id, content) =>
|
||||
{
|
||||
device.SetTemperatureFormat(true);
|
||||
});
|
||||
|
||||
AddAction("/setTemperatureUnitsToFahrenheit", (id, content) =>
|
||||
{
|
||||
device.SetTemperatureFormat(false);
|
||||
});
|
||||
|
||||
device.TemperatureFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
|
||||
device.TemperatureInCFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
// format the temperature to a string with one decimal place
|
||||
var tempString = string.Format("{0}.{1}", device.TemperatureFeedback.UShortValue / 10, device.TemperatureFeedback.UShortValue % 10);
|
||||
|
||||
var state = new ITemperatureSensorStateMessage
|
||||
{
|
||||
Temperature = tempString,
|
||||
TemperatureInCelsius = device.TemperatureInCFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
public class ITemperatureSensorStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("temperature")]
|
||||
public string Temperature { get; set; }
|
||||
|
||||
[JsonProperty("temperatureInCelsius")]
|
||||
public bool TemperatureInCelsius { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Lighting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class ILightingScenesMessenger : MessengerBase
|
||||
{
|
||||
protected ILightingScenes Device { get; private set; }
|
||||
|
||||
public ILightingScenesMessenger(string key, ILightingScenes device, string messagePath)
|
||||
: base(key, messagePath, device as Device)
|
||||
{
|
||||
Device = device ?? throw new ArgumentNullException("device");
|
||||
Device.LightingSceneChange += new EventHandler<LightingSceneChangeEventArgs>(LightingDevice_LightingSceneChange);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void LightingDevice_LightingSceneChange(object sender, LightingSceneChangeEventArgs e)
|
||||
{
|
||||
var state = new LightingBaseStateMessage
|
||||
{
|
||||
CurrentLightingScene = e.CurrentLightingScene
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/selectScene", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<LightingScene>();
|
||||
Device.SelectScene(s);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new LightingBaseStateMessage
|
||||
{
|
||||
Scenes = Device.LightingScenes,
|
||||
CurrentLightingScene = Device.CurrentLightingScene
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
public class LightingBaseStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("scenes", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<LightingScene> Scenes { get; set; }
|
||||
|
||||
[JsonProperty("currentLightingScene", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public LightingScene CurrentLightingScene { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a messaging bridge
|
||||
/// </summary>
|
||||
public abstract class MessengerBase : EssentialsDevice, IMobileControlMessenger
|
||||
{
|
||||
protected IKeyName _device;
|
||||
|
||||
private readonly List<string> _deviceInterfaces;
|
||||
|
||||
private readonly Dictionary<string, Action<string, JToken>> _actions = new Dictionary<string, Action<string, JToken>>();
|
||||
|
||||
public string DeviceKey => _device?.Key ?? "";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
||||
public IMobileControl AppServerController { get; private set; }
|
||||
|
||||
public string MessagePath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
protected MessengerBase(string key, string messagePath)
|
||||
: base(key)
|
||||
{
|
||||
Key = key;
|
||||
|
||||
if (string.IsNullOrEmpty(messagePath))
|
||||
throw new ArgumentException("messagePath must not be empty or null");
|
||||
|
||||
MessagePath = messagePath;
|
||||
}
|
||||
|
||||
protected MessengerBase(string key, string messagePath, IKeyName device)
|
||||
: this(key, messagePath)
|
||||
{
|
||||
_device = device;
|
||||
|
||||
_deviceInterfaces = GetInterfaces(_device as Device);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the interfaces implmented on the device
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <returns></returns>
|
||||
private List<string> GetInterfaces(Device device)
|
||||
{
|
||||
return device?.GetType().GetInterfaces().Select((i) => i.Name).ToList() ?? new List<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers this messenger with appserver controller
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
public void RegisterWithAppServer(IMobileControl appServerController)
|
||||
{
|
||||
AppServerController = appServerController ?? throw new ArgumentNullException("appServerController");
|
||||
|
||||
AppServerController.AddAction(this, HandleMessage);
|
||||
|
||||
RegisterActions();
|
||||
}
|
||||
|
||||
private void HandleMessage(string path, string id, JToken content)
|
||||
{
|
||||
// replace base path with empty string. Should leave something like /fullStatus
|
||||
var route = path.Replace(MessagePath, string.Empty);
|
||||
|
||||
if (!_actions.TryGetValue(route, out var action))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Executing action for path {path}", this, path);
|
||||
|
||||
action(id, content);
|
||||
}
|
||||
|
||||
protected void AddAction(string path, Action<string, JToken> action)
|
||||
{
|
||||
if (_actions.ContainsKey(path))
|
||||
{
|
||||
//Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, $"Messenger {Key} already has action registered at {path}", this);
|
||||
return;
|
||||
}
|
||||
|
||||
_actions.Add(path, action);
|
||||
}
|
||||
|
||||
public List<string> GetActionPaths()
|
||||
{
|
||||
return _actions.Keys.ToList();
|
||||
}
|
||||
|
||||
protected void RemoveAction(string path)
|
||||
{
|
||||
if (!_actions.ContainsKey(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_actions.Remove(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implemented in extending classes. Wire up API calls and feedback here
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
protected virtual void RegisterActions()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for posting status message
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="message"></param>
|
||||
protected void PostStatusMessage(DeviceStateMessageBase message, string clientId = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
throw new ArgumentNullException("message");
|
||||
}
|
||||
|
||||
if (_device == null)
|
||||
{
|
||||
throw new ArgumentNullException("device");
|
||||
}
|
||||
|
||||
message.SetInterfaces(_deviceInterfaces);
|
||||
|
||||
message.Key = _device.Key;
|
||||
|
||||
message.Name = _device.Name;
|
||||
|
||||
PostStatusMessage(JToken.FromObject(message), MessagePath, clientId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception posting status message", this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void PostStatusMessage(string type, DeviceStateMessageBase deviceState, string clientId = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Debug.Console(2, this, "*********************Setting DeviceStateMessageProperties on MobileControlResponseMessage");
|
||||
deviceState.SetInterfaces(_deviceInterfaces);
|
||||
|
||||
deviceState.Key = _device.Key;
|
||||
|
||||
deviceState.Name = _device.Name;
|
||||
|
||||
deviceState.MessageBasePath = MessagePath;
|
||||
|
||||
PostStatusMessage(JToken.FromObject(deviceState), type, clientId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception posting status message", this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void PostStatusMessage(JToken content, string type = "", string clientId = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
AppServerController?.SendMessageObject(new MobileControlMessage { Type = !string.IsNullOrEmpty(type) ? type : MessagePath, ClientId = clientId, Content = content });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception posting status message", this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void PostEventMessage(DeviceEventMessageBase message)
|
||||
{
|
||||
message.Key = _device.Key;
|
||||
|
||||
message.Name = _device.Name;
|
||||
|
||||
AppServerController?.SendMessageObject(new MobileControlMessage
|
||||
{
|
||||
Type = $"/event{MessagePath}/{message.EventType}",
|
||||
Content = JToken.FromObject(message),
|
||||
});
|
||||
}
|
||||
|
||||
protected void PostEventMessage(DeviceEventMessageBase message, string eventType)
|
||||
{
|
||||
message.Key = _device.Key;
|
||||
|
||||
message.Name = _device.Name;
|
||||
|
||||
message.EventType = eventType;
|
||||
|
||||
AppServerController?.SendMessageObject(new MobileControlMessage
|
||||
{
|
||||
Type = $"/event{MessagePath}/{eventType}",
|
||||
Content = JToken.FromObject(message),
|
||||
});
|
||||
}
|
||||
|
||||
protected void PostEventMessage(string eventType)
|
||||
{
|
||||
AppServerController?.SendMessageObject(new MobileControlMessage
|
||||
{
|
||||
Type = $"/event{MessagePath}/{eventType}",
|
||||
Content = JToken.FromObject(new { }),
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public abstract class DeviceMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The device key
|
||||
/// </summary>
|
||||
[JsonProperty("key")]
|
||||
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")]
|
||||
public string MessageBasePath { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for state messages that includes the type of message and the implmented interfaces
|
||||
/// </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; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public static class PressAndHoldHandler
|
||||
{
|
||||
private const long ButtonHeartbeatInterval = 1000;
|
||||
|
||||
private static readonly Dictionary<string, CTimer> _pushedActions = new Dictionary<string, CTimer>();
|
||||
|
||||
private static readonly Dictionary<string, Action<string, Action<bool>>> _pushedActionHandlers;
|
||||
|
||||
static PressAndHoldHandler()
|
||||
{
|
||||
_pushedActionHandlers = new Dictionary<string, Action<string, Action<bool>>>
|
||||
{
|
||||
{"pressed", AddTimer },
|
||||
{"held", ResetTimer },
|
||||
{"released", StopTimer }
|
||||
};
|
||||
}
|
||||
|
||||
private static void AddTimer(string deviceKey, Action<bool> action)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Attempting to add timer for {deviceKey}", deviceKey);
|
||||
|
||||
if (_pushedActions.TryGetValue(deviceKey, out CTimer cancelTimer))
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Timer for {deviceKey} already exists", deviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Adding timer for {deviceKey} with due time {dueTime}", deviceKey, ButtonHeartbeatInterval);
|
||||
|
||||
action(true);
|
||||
|
||||
cancelTimer = new CTimer(o =>
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Timer expired for {deviceKey}", deviceKey);
|
||||
|
||||
action(false);
|
||||
|
||||
_pushedActions.Remove(deviceKey);
|
||||
}, ButtonHeartbeatInterval);
|
||||
|
||||
_pushedActions.Add(deviceKey, cancelTimer);
|
||||
}
|
||||
|
||||
private static void ResetTimer(string deviceKey, Action<bool> action)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Attempting to reset timer for {deviceKey}", deviceKey);
|
||||
|
||||
if (!_pushedActions.TryGetValue(deviceKey, out CTimer cancelTimer))
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Timer for {deviceKey} not found", deviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Resetting timer for {deviceKey} with due time {dueTime}", deviceKey, ButtonHeartbeatInterval);
|
||||
|
||||
cancelTimer.Reset(ButtonHeartbeatInterval);
|
||||
}
|
||||
|
||||
private static void StopTimer(string deviceKey, Action<bool> action)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Attempting to stop timer for {deviceKey}", deviceKey);
|
||||
|
||||
if (!_pushedActions.TryGetValue(deviceKey, out CTimer cancelTimer))
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Timer for {deviceKey} not found", deviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Stopping timer for {deviceKey} with due time {dueTime}", deviceKey, ButtonHeartbeatInterval);
|
||||
|
||||
action(false);
|
||||
cancelTimer.Stop();
|
||||
_pushedActions.Remove(deviceKey);
|
||||
}
|
||||
|
||||
public static Action<string, Action<bool>> GetPressAndHoldHandler(string value)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Getting press and hold handler for {value}", value);
|
||||
|
||||
if (!_pushedActionHandlers.TryGetValue(value, out Action<string, Action<bool>> handler))
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Press and hold handler for {value} not found", value);
|
||||
return null;
|
||||
}
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Got handler for {value}", value);
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
public static void HandlePressAndHold(string deviceKey, JToken content, Action<bool> action)
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Handling press and hold message of {type} for {deviceKey}", msg.Value, deviceKey);
|
||||
|
||||
var timerHandler = GetPressAndHoldHandler(msg.Value);
|
||||
|
||||
if (timerHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
timerHandler(deviceKey, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class RoomEventScheduleMessenger : MessengerBase
|
||||
{
|
||||
private readonly IRoomEventSchedule _room;
|
||||
|
||||
|
||||
public RoomEventScheduleMessenger(string key, string messagePath, IRoomEventSchedule room)
|
||||
: base(key, messagePath, room as Device)
|
||||
{
|
||||
_room = room;
|
||||
}
|
||||
|
||||
#region Overrides of MessengerBase
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/saveScheduledEvents", (id, content) => SaveScheduledEvents(content.ToObject<List<ScheduledEventConfig>>()));
|
||||
AddAction("/status", (id, content) =>
|
||||
{
|
||||
var events = _room.GetScheduledEvents();
|
||||
|
||||
SendFullStatus(events);
|
||||
});
|
||||
|
||||
_room.ScheduledEventsChanged += (sender, args) => SendFullStatus(args.ScheduledEvents);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void SaveScheduledEvents(List<ScheduledEventConfig> events)
|
||||
{
|
||||
foreach (var evt in events)
|
||||
{
|
||||
SaveScheduledEvent(evt);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveScheduledEvent(ScheduledEventConfig eventConfig)
|
||||
{
|
||||
try
|
||||
{
|
||||
_room.AddOrUpdateScheduledEvent(eventConfig);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.LogException(ex,"Exception saving event");
|
||||
}
|
||||
}
|
||||
|
||||
private void SendFullStatus(List<ScheduledEventConfig> events)
|
||||
{
|
||||
|
||||
var message = new RoomEventScheduleStateMessage
|
||||
{
|
||||
ScheduleEvents = events,
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public class RoomEventScheduleStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("scheduleEvents")]
|
||||
public List<ScheduledEventConfig> ScheduleEvents { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class SIMPLAtcMessenger : MessengerBase
|
||||
{
|
||||
private readonly BasicTriList _eisc;
|
||||
|
||||
public SIMPLAtcJoinMap JoinMap { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private readonly CodecActiveCallItem _currentCallItem;
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="eisc"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
public SIMPLAtcMessenger(string key, BasicTriList eisc, string messagePath)
|
||||
: base(key, messagePath)
|
||||
{
|
||||
_eisc = eisc;
|
||||
|
||||
JoinMap = new SIMPLAtcJoinMap(201);
|
||||
|
||||
_currentCallItem = new CodecActiveCallItem { Type = eCodecCallType.Audio, Id = "-audio-" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void SendFullStatus()
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
calls = GetCurrentCallList(),
|
||||
currentCallString = _eisc.GetString(JoinMap.CurrentCallName.JoinNumber),
|
||||
currentDialString = _eisc.GetString(JoinMap.CurrentDialString.JoinNumber),
|
||||
isInCall = _eisc.GetString(JoinMap.HookState.JoinNumber) == "Connected"
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
//EISC.SetStringSigAction(SCurrentDialString, s => PostStatusMessage(new { currentDialString = s }));
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.HookState.JoinNumber, s =>
|
||||
{
|
||||
_currentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true);
|
||||
//GetCurrentCallList();
|
||||
SendFullStatus();
|
||||
});
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.CurrentCallNumber.JoinNumber, s =>
|
||||
{
|
||||
_currentCallItem.Number = s;
|
||||
SendCallsList();
|
||||
});
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.CurrentCallName.JoinNumber, s =>
|
||||
{
|
||||
_currentCallItem.Name = s;
|
||||
SendCallsList();
|
||||
});
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.CallDirection.JoinNumber, s =>
|
||||
{
|
||||
_currentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true);
|
||||
SendCallsList();
|
||||
});
|
||||
|
||||
// Add press and holds using helper
|
||||
//Action<string, uint> addPhAction = (s, u) =>
|
||||
// AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => _eisc.SetBool(u, b)));
|
||||
|
||||
// Add straight pulse calls
|
||||
void addAction(string s, uint u) =>
|
||||
AddAction(s, (id, content) => _eisc.PulseBool(u, 100));
|
||||
addAction("/endCallById", JoinMap.EndCall.JoinNumber);
|
||||
addAction("/endAllCalls", JoinMap.EndCall.JoinNumber);
|
||||
addAction("/acceptById", JoinMap.IncomingAnswer.JoinNumber);
|
||||
addAction("/rejectById", JoinMap.IncomingReject.JoinNumber);
|
||||
|
||||
var speeddialStart = JoinMap.SpeedDialStart.JoinNumber;
|
||||
var speeddialEnd = JoinMap.SpeedDialStart.JoinNumber + JoinMap.SpeedDialStart.JoinSpan;
|
||||
|
||||
var speedDialIndex = 1;
|
||||
for (uint i = speeddialStart; i < speeddialEnd; i++)
|
||||
{
|
||||
addAction(string.Format("/speedDial{0}", speedDialIndex), i);
|
||||
speedDialIndex++;
|
||||
}
|
||||
|
||||
// Get status
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
// Dial on string
|
||||
AddAction("/dial",
|
||||
(id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
_eisc.SetString(JoinMap.CurrentDialString.JoinNumber, msg.Value);
|
||||
});
|
||||
// Pulse DTMF
|
||||
AddAction("/dtmf", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var join = JoinMap.Joins[s.Value];
|
||||
if (join != null)
|
||||
{
|
||||
if (join.JoinNumber > 0)
|
||||
{
|
||||
_eisc.PulseBool(join.JoinNumber, 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void SendCallsList()
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
calls = GetCurrentCallList(),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns the
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private List<CodecActiveCallItem> GetCurrentCallList()
|
||||
{
|
||||
return _currentCallItem.Status == eCodecCallStatus.Disconnected
|
||||
? new List<CodecActiveCallItem>()
|
||||
: new List<CodecActiveCallItem> { _currentCallItem };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class SIMPLCameraMessenger : MessengerBase
|
||||
{
|
||||
private readonly BasicTriList _eisc;
|
||||
|
||||
private readonly CameraControllerJoinMap _joinMap;
|
||||
|
||||
|
||||
public SIMPLCameraMessenger(string key, BasicTriList eisc, string messagePath, uint joinStart)
|
||||
: base(key, messagePath)
|
||||
{
|
||||
_eisc = eisc;
|
||||
|
||||
_joinMap = new CameraControllerJoinMap(joinStart);
|
||||
|
||||
_eisc.SetUShortSigAction(_joinMap.NumberOfPresets.JoinNumber, u => SendCameraFullMessageObject());
|
||||
|
||||
_eisc.SetBoolSigAction(_joinMap.CameraModeAuto.JoinNumber, b => PostCameraMode());
|
||||
_eisc.SetBoolSigAction(_joinMap.CameraModeManual.JoinNumber, b => PostCameraMode());
|
||||
_eisc.SetBoolSigAction(_joinMap.CameraModeOff.JoinNumber, b => PostCameraMode());
|
||||
}
|
||||
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject());
|
||||
|
||||
// Add press and holds using helper action
|
||||
void addPhAction(string s, uint u) =>
|
||||
AddAction(s, (id, content) => HandleCameraPressAndHold(content, b => _eisc.SetBool(u, b)));
|
||||
addPhAction("/cameraUp", _joinMap.TiltUp.JoinNumber);
|
||||
addPhAction("/cameraDown", _joinMap.TiltDown.JoinNumber);
|
||||
addPhAction("/cameraLeft", _joinMap.PanLeft.JoinNumber);
|
||||
addPhAction("/cameraRight", _joinMap.PanRight.JoinNumber);
|
||||
addPhAction("/cameraZoomIn", _joinMap.ZoomIn.JoinNumber);
|
||||
addPhAction("/cameraZoomOut", _joinMap.ZoomOut.JoinNumber);
|
||||
|
||||
void addAction(string s, uint u) =>
|
||||
AddAction(s, (id, content) => _eisc.PulseBool(u, 100));
|
||||
|
||||
addAction("/cameraModeAuto", _joinMap.CameraModeAuto.JoinNumber);
|
||||
addAction("/cameraModeManual", _joinMap.CameraModeManual.JoinNumber);
|
||||
addAction("/cameraModeOff", _joinMap.CameraModeOff.JoinNumber);
|
||||
|
||||
var presetStart = _joinMap.PresetRecallStart.JoinNumber;
|
||||
var presetEnd = _joinMap.PresetRecallStart.JoinNumber + _joinMap.PresetRecallStart.JoinSpan;
|
||||
|
||||
int presetId = 1;
|
||||
// camera presets
|
||||
for (uint i = presetStart; i <= presetEnd; i++)
|
||||
{
|
||||
addAction("/cameraPreset" + (presetId), i);
|
||||
presetId++;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleCameraPressAndHold(JToken content, Action<bool> cameraAction)
|
||||
{
|
||||
var state = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value);
|
||||
if (timerHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
timerHandler(state.Value, cameraAction);
|
||||
|
||||
cameraAction(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
public void CustomUnregisterWithAppServer(IMobileControl appServerController)
|
||||
{
|
||||
appServerController.RemoveAction(MessagePath + "/fullStatus");
|
||||
|
||||
appServerController.RemoveAction(MessagePath + "/cameraUp");
|
||||
appServerController.RemoveAction(MessagePath + "/cameraDown");
|
||||
appServerController.RemoveAction(MessagePath + "/cameraLeft");
|
||||
appServerController.RemoveAction(MessagePath + "/cameraRight");
|
||||
appServerController.RemoveAction(MessagePath + "/cameraZoomIn");
|
||||
appServerController.RemoveAction(MessagePath + "/cameraZoomOut");
|
||||
appServerController.RemoveAction(MessagePath + "/cameraModeAuto");
|
||||
appServerController.RemoveAction(MessagePath + "/cameraModeManual");
|
||||
appServerController.RemoveAction(MessagePath + "/cameraModeOff");
|
||||
|
||||
_eisc.SetUShortSigAction(_joinMap.NumberOfPresets.JoinNumber, null);
|
||||
|
||||
_eisc.SetBoolSigAction(_joinMap.CameraModeAuto.JoinNumber, null);
|
||||
_eisc.SetBoolSigAction(_joinMap.CameraModeManual.JoinNumber, null);
|
||||
_eisc.SetBoolSigAction(_joinMap.CameraModeOff.JoinNumber, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to update the full status of the camera
|
||||
/// </summary>
|
||||
private void SendCameraFullMessageObject()
|
||||
{
|
||||
var presetList = new List<CameraPreset>();
|
||||
|
||||
// Build a list of camera presets based on the names and count
|
||||
if (_eisc.GetBool(_joinMap.SupportsPresets.JoinNumber))
|
||||
{
|
||||
var presetStart = _joinMap.PresetLabelStart.JoinNumber;
|
||||
var presetEnd = _joinMap.PresetLabelStart.JoinNumber + _joinMap.NumberOfPresets.JoinNumber;
|
||||
|
||||
var presetId = 1;
|
||||
for (uint i = presetStart; i < presetEnd; i++)
|
||||
{
|
||||
var presetName = _eisc.GetString(i);
|
||||
var preset = new CameraPreset(presetId, presetName, string.IsNullOrEmpty(presetName), true);
|
||||
presetList.Add(preset);
|
||||
presetId++;
|
||||
}
|
||||
}
|
||||
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
cameraMode = GetCameraMode(),
|
||||
hasPresets = _eisc.GetBool(_joinMap.SupportsPresets.JoinNumber),
|
||||
presets = presetList
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void PostCameraMode()
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
cameraMode = GetCameraMode()
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the current camera mode
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string GetCameraMode()
|
||||
{
|
||||
string m;
|
||||
if (_eisc.GetBool(_joinMap.CameraModeAuto.JoinNumber)) m = eCameraControlMode.Auto.ToString().ToLower();
|
||||
else if (_eisc.GetBool(_joinMap.CameraModeManual.JoinNumber))
|
||||
m = eCameraControlMode.Manual.ToString().ToLower();
|
||||
else m = eCameraControlMode.Off.ToString().ToLower();
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class SimplDirectRouteMessenger : MessengerBase
|
||||
{
|
||||
private readonly BasicTriList _eisc;
|
||||
|
||||
public MobileControlSIMPLRunDirectRouteActionJoinMap JoinMap { get; private set; }
|
||||
|
||||
public Dictionary<string, DestinationListItem> DestinationList { get; set; }
|
||||
|
||||
public SimplDirectRouteMessenger(string key, BasicTriList eisc, string messagePath) : base(key, messagePath)
|
||||
{
|
||||
_eisc = eisc;
|
||||
|
||||
JoinMap = new MobileControlSIMPLRunDirectRouteActionJoinMap(851);
|
||||
|
||||
DestinationList = new Dictionary<string, DestinationListItem>();
|
||||
}
|
||||
|
||||
#region Overrides of MessengerBase
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
Debug.Console(2, "********** Direct Route Messenger CustomRegisterWithAppServer **********");
|
||||
|
||||
|
||||
//Audio source
|
||||
_eisc.SetStringSigAction(JoinMap.SourceForDestinationAudio.JoinNumber,
|
||||
s => PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
selectedSourceKey = s,
|
||||
})
|
||||
));
|
||||
|
||||
AddAction("/programAudio/selectSource", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
_eisc.StringInput[JoinMap.SourceForDestinationAudio.JoinNumber].StringValue = msg.Value;
|
||||
});
|
||||
|
||||
AddAction("/fullStatus", (id, content) =>
|
||||
{
|
||||
foreach (var dest in DestinationList)
|
||||
{
|
||||
var key = dest.Key;
|
||||
var item = dest.Value;
|
||||
|
||||
var source =
|
||||
_eisc.StringOutput[(uint)(JoinMap.SourceForDestinationJoinStart.JoinNumber + item.Order)].StringValue;
|
||||
|
||||
UpdateSourceForDestination(source, key);
|
||||
}
|
||||
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
selectedSourceKey = _eisc.StringOutput[JoinMap.SourceForDestinationAudio.JoinNumber].StringValue
|
||||
})
|
||||
);
|
||||
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
advancedSharingActive = _eisc.BooleanOutput[JoinMap.AdvancedSharingModeFb.JoinNumber].BoolValue
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
AddAction("/advancedSharingMode", (id, content) =>
|
||||
{
|
||||
var b = content.ToObject<MobileControlSimpleContent<bool>>();
|
||||
|
||||
Debug.Console(1, "Current Sharing Mode: {2}\r\nadvanced sharing mode: {0} join number: {1}", b.Value,
|
||||
JoinMap.AdvancedSharingModeOn.JoinNumber,
|
||||
_eisc.BooleanOutput[JoinMap.AdvancedSharingModeOn.JoinNumber].BoolValue);
|
||||
|
||||
_eisc.SetBool(JoinMap.AdvancedSharingModeOn.JoinNumber, b.Value);
|
||||
_eisc.SetBool(JoinMap.AdvancedSharingModeOff.JoinNumber, !b.Value);
|
||||
_eisc.PulseBool(JoinMap.AdvancedSharingModeToggle.JoinNumber);
|
||||
});
|
||||
|
||||
_eisc.SetBoolSigAction(JoinMap.AdvancedSharingModeFb.JoinNumber,
|
||||
(b) => PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
advancedSharingActive = b
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
public void RegisterForDestinationPaths()
|
||||
{
|
||||
//handle routing feedback from SIMPL
|
||||
foreach (var destination in DestinationList)
|
||||
{
|
||||
var key = destination.Key;
|
||||
var dest = destination.Value;
|
||||
|
||||
_eisc.SetStringSigAction((uint)(JoinMap.SourceForDestinationJoinStart.JoinNumber + dest.Order),
|
||||
s => UpdateSourceForDestination(s, key));
|
||||
|
||||
AddAction($"/{key}/selectSource", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
_eisc.StringInput[(uint)(JoinMap.SourceForDestinationJoinStart.JoinNumber + dest.Order)].StringValue = s.Value;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void UpdateSourceForDestination(string sourceKey, string destKey)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
selectedSourceKey = sourceKey
|
||||
}), $"{MessagePath}/{destKey}/currentSource");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
|
||||
public class SIMPLRouteMessenger : MessengerBase
|
||||
{
|
||||
private readonly BasicTriList _eisc;
|
||||
|
||||
private readonly uint _joinStart;
|
||||
|
||||
public class StringJoin
|
||||
{
|
||||
/// <summary>
|
||||
/// 1
|
||||
/// </summary>
|
||||
public const uint CurrentSource = 1;
|
||||
}
|
||||
|
||||
public SIMPLRouteMessenger(string key, BasicTriList eisc, string messagePath, uint joinStart)
|
||||
: base(key, messagePath)
|
||||
{
|
||||
_eisc = eisc;
|
||||
_joinStart = joinStart - 1;
|
||||
|
||||
_eisc.SetStringSigAction(_joinStart + StringJoin.CurrentSource, SendRoutingFullMessageObject);
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus",
|
||||
(id, content) => SendRoutingFullMessageObject(_eisc.GetString(_joinStart + StringJoin.CurrentSource)));
|
||||
|
||||
AddAction("/source", (id, content) =>
|
||||
{
|
||||
var c = content.ToObject<SourceSelectMessageContent>();
|
||||
|
||||
_eisc.SetString(_joinStart + StringJoin.CurrentSource, c.SourceListItemKey);
|
||||
});
|
||||
}
|
||||
|
||||
public void CustomUnregisterWithAppServer(IMobileControl appServerController)
|
||||
{
|
||||
appServerController.RemoveAction(MessagePath + "/fullStatus");
|
||||
appServerController.RemoveAction(MessagePath + "/source");
|
||||
|
||||
_eisc.SetStringSigAction(_joinStart + StringJoin.CurrentSource, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to update full status of the routing device
|
||||
/// </summary>
|
||||
private void SendRoutingFullMessageObject(string sourceKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceKey))
|
||||
sourceKey = "none";
|
||||
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
selectedSourceKey = sourceKey
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,475 +0,0 @@
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class SIMPLVtcMessenger : MessengerBase
|
||||
{
|
||||
private readonly BasicTriList _eisc;
|
||||
|
||||
public SIMPLVtcJoinMap JoinMap { get; private set; }
|
||||
|
||||
private readonly CodecActiveCallItem _currentCallItem;
|
||||
|
||||
private CodecActiveCallItem _incomingCallItem;
|
||||
|
||||
private ushort _previousDirectoryLength = 701;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="eisc"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
public SIMPLVtcMessenger(string key, BasicTriList eisc, string messagePath)
|
||||
: base(key, messagePath)
|
||||
{
|
||||
_eisc = eisc;
|
||||
|
||||
JoinMap = new SIMPLVtcJoinMap(1001);
|
||||
|
||||
_currentCallItem = new CodecActiveCallItem { Type = eCodecCallType.Video, Id = "-video-" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
_eisc.SetStringSigAction(JoinMap.HookState.JoinNumber, s =>
|
||||
{
|
||||
_currentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true);
|
||||
PostFullStatus(); // SendCallsList();
|
||||
});
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.CurrentCallNumber.JoinNumber, s =>
|
||||
{
|
||||
_currentCallItem.Number = s;
|
||||
PostCallsList();
|
||||
});
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.CurrentCallName.JoinNumber, s =>
|
||||
{
|
||||
_currentCallItem.Name = s;
|
||||
PostCallsList();
|
||||
});
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.CallDirection.JoinNumber, s =>
|
||||
{
|
||||
_currentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true);
|
||||
PostCallsList();
|
||||
});
|
||||
|
||||
_eisc.SetBoolSigAction(JoinMap.IncomingCall.JoinNumber, b =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
var ica = new CodecActiveCallItem
|
||||
{
|
||||
Direction = eCodecCallDirection.Incoming,
|
||||
Id = "-video-incoming",
|
||||
Name = _eisc.GetString(JoinMap.IncomingCallName.JoinNumber),
|
||||
Number = _eisc.GetString(JoinMap.IncomingCallNumber.JoinNumber),
|
||||
Status = eCodecCallStatus.Ringing,
|
||||
Type = eCodecCallType.Video
|
||||
};
|
||||
_incomingCallItem = ica;
|
||||
}
|
||||
else
|
||||
{
|
||||
_incomingCallItem = null;
|
||||
}
|
||||
PostCallsList();
|
||||
});
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.IncomingCallName.JoinNumber, s =>
|
||||
{
|
||||
if (_incomingCallItem != null)
|
||||
{
|
||||
_incomingCallItem.Name = s;
|
||||
PostCallsList();
|
||||
}
|
||||
});
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.IncomingCallNumber.JoinNumber, s =>
|
||||
{
|
||||
if (_incomingCallItem != null)
|
||||
{
|
||||
_incomingCallItem.Number = s;
|
||||
PostCallsList();
|
||||
}
|
||||
});
|
||||
|
||||
_eisc.SetBoolSigAction(JoinMap.CameraSupportsAutoMode.JoinNumber, b => PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
cameraSupportsAutoMode = b
|
||||
})));
|
||||
_eisc.SetBoolSigAction(JoinMap.CameraSupportsOffMode.JoinNumber, b => PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
cameraSupportsOffMode = b
|
||||
})));
|
||||
|
||||
// Directory insanity
|
||||
_eisc.SetUShortSigAction(JoinMap.DirectoryRowCount.JoinNumber, u =>
|
||||
{
|
||||
// The length of the list comes in before the list does.
|
||||
// Splice the sig change operation onto the last string sig that will be changing
|
||||
// when the directory entries make it through.
|
||||
if (_previousDirectoryLength > 0)
|
||||
{
|
||||
_eisc.ClearStringSigAction(JoinMap.DirectoryEntriesStart.JoinNumber + _previousDirectoryLength - 1);
|
||||
}
|
||||
_eisc.SetStringSigAction(JoinMap.DirectoryEntriesStart.JoinNumber + u - 1, s => PostDirectory());
|
||||
_previousDirectoryLength = u;
|
||||
});
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.DirectoryEntrySelectedName.JoinNumber, s => PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
directoryContactSelected = new
|
||||
{
|
||||
name = _eisc.GetString(JoinMap.DirectoryEntrySelectedName.JoinNumber),
|
||||
}
|
||||
})));
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.DirectoryEntrySelectedNumber.JoinNumber, s => PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
directoryContactSelected = new
|
||||
{
|
||||
number = _eisc.GetString(JoinMap.DirectoryEntrySelectedNumber.JoinNumber),
|
||||
}
|
||||
})));
|
||||
|
||||
_eisc.SetStringSigAction(JoinMap.DirectorySelectedFolderName.JoinNumber, s => PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
directorySelectedFolderName = _eisc.GetString(JoinMap.DirectorySelectedFolderName.JoinNumber)
|
||||
})));
|
||||
|
||||
_eisc.SetSigTrueAction(JoinMap.CameraModeAuto.JoinNumber, PostCameraMode);
|
||||
_eisc.SetSigTrueAction(JoinMap.CameraModeManual.JoinNumber, PostCameraMode);
|
||||
_eisc.SetSigTrueAction(JoinMap.CameraModeOff.JoinNumber, PostCameraMode);
|
||||
|
||||
_eisc.SetBoolSigAction(JoinMap.CameraSelfView.JoinNumber, b => PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
cameraSelfView = b
|
||||
})));
|
||||
|
||||
_eisc.SetUShortSigAction(JoinMap.CameraNumberSelect.JoinNumber, u => PostSelectedCamera());
|
||||
|
||||
|
||||
// Add press and holds using helper action
|
||||
void addPhAction(string s, uint u) =>
|
||||
AddAction(s, (id, content) => HandleCameraPressAndHold(content, b => _eisc.SetBool(u, b)));
|
||||
addPhAction("/cameraUp", JoinMap.CameraTiltUp.JoinNumber);
|
||||
addPhAction("/cameraDown", JoinMap.CameraTiltDown.JoinNumber);
|
||||
addPhAction("/cameraLeft", JoinMap.CameraPanLeft.JoinNumber);
|
||||
addPhAction("/cameraRight", JoinMap.CameraPanRight.JoinNumber);
|
||||
addPhAction("/cameraZoomIn", JoinMap.CameraZoomIn.JoinNumber);
|
||||
addPhAction("/cameraZoomOut", JoinMap.CameraZoomOut.JoinNumber);
|
||||
|
||||
// Add straight pulse calls using helper action
|
||||
void addAction(string s, uint u) =>
|
||||
AddAction(s, (id, content) => _eisc.PulseBool(u, 100));
|
||||
addAction("/endCallById", JoinMap.EndCall.JoinNumber);
|
||||
addAction("/endAllCalls", JoinMap.EndCall.JoinNumber);
|
||||
addAction("/acceptById", JoinMap.IncomingAnswer.JoinNumber);
|
||||
addAction("/rejectById", JoinMap.IncomingReject.JoinNumber);
|
||||
|
||||
var speeddialStart = JoinMap.SpeedDialStart.JoinNumber;
|
||||
var speeddialEnd = JoinMap.SpeedDialStart.JoinNumber + JoinMap.SpeedDialStart.JoinSpan;
|
||||
|
||||
var speedDialIndex = 1;
|
||||
for (uint i = speeddialStart; i < speeddialEnd; i++)
|
||||
{
|
||||
addAction(string.Format("/speedDial{0}", speedDialIndex), i);
|
||||
speedDialIndex++;
|
||||
}
|
||||
|
||||
addAction("/cameraModeAuto", JoinMap.CameraModeAuto.JoinNumber);
|
||||
addAction("/cameraModeManual", JoinMap.CameraModeManual.JoinNumber);
|
||||
addAction("/cameraModeOff", JoinMap.CameraModeOff.JoinNumber);
|
||||
addAction("/cameraSelfView", JoinMap.CameraSelfView.JoinNumber);
|
||||
addAction("/cameraLayout", JoinMap.CameraLayout.JoinNumber);
|
||||
|
||||
AddAction("/cameraSelect", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
SelectCamera(s.Value);
|
||||
});
|
||||
|
||||
// camera presets
|
||||
for (uint i = 0; i < 6; i++)
|
||||
{
|
||||
addAction("/cameraPreset" + (i + 1), JoinMap.CameraPresetStart.JoinNumber + i);
|
||||
}
|
||||
|
||||
AddAction("/isReady", (id, content) => PostIsReady());
|
||||
// Get status
|
||||
AddAction("/fullStatus", (id, content) => PostFullStatus());
|
||||
// Dial on string
|
||||
AddAction("/dial", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
_eisc.SetString(JoinMap.CurrentDialString.JoinNumber, s.Value);
|
||||
});
|
||||
// Pulse DTMF
|
||||
AddAction("/dtmf", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
var join = JoinMap.Joins[s.Value];
|
||||
if (join != null)
|
||||
{
|
||||
if (join.JoinNumber > 0)
|
||||
{
|
||||
_eisc.PulseBool(join.JoinNumber, 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Directory madness
|
||||
AddAction("/directoryRoot",
|
||||
(id, content) => _eisc.PulseBool(JoinMap.DirectoryRoot.JoinNumber));
|
||||
AddAction("/directoryBack",
|
||||
(id, content) => _eisc.PulseBool(JoinMap.DirectoryFolderBack.JoinNumber));
|
||||
AddAction("/directoryById", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
// the id should contain the line number to forward to simpl
|
||||
try
|
||||
{
|
||||
var u = ushort.Parse(s.Value);
|
||||
_eisc.SetUshort(JoinMap.DirectorySelectRow.JoinNumber, u);
|
||||
_eisc.PulseBool(JoinMap.DirectoryLineSelected.JoinNumber);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Warning,
|
||||
"/directoryById request contains non-numeric ID incompatible with SIMPL bridge");
|
||||
}
|
||||
});
|
||||
AddAction("/directorySelectContact", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
try
|
||||
{
|
||||
var u = ushort.Parse(s.Value);
|
||||
_eisc.SetUshort(JoinMap.DirectorySelectRow.JoinNumber, u);
|
||||
_eisc.PulseBool(JoinMap.DirectoryLineSelected.JoinNumber);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(2, this, "Error parsing contact from {0} for path /directorySelectContact", s);
|
||||
}
|
||||
});
|
||||
AddAction("/directoryDialContact",
|
||||
(id, content) => _eisc.PulseBool(JoinMap.DirectoryDialSelectedLine.JoinNumber));
|
||||
AddAction("/getDirectory", (id, content) =>
|
||||
{
|
||||
if (_eisc.GetUshort(JoinMap.DirectoryRowCount.JoinNumber) > 0)
|
||||
{
|
||||
PostDirectory();
|
||||
}
|
||||
else
|
||||
{
|
||||
_eisc.PulseBool(JoinMap.DirectoryRoot.JoinNumber);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleCameraPressAndHold(JToken content, Action<bool> cameraAction)
|
||||
{
|
||||
var state = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value);
|
||||
if (timerHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
timerHandler(state.Value, cameraAction);
|
||||
|
||||
cameraAction(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
private void PostFullStatus()
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
calls = GetCurrentCallList(),
|
||||
cameraMode = GetCameraMode(),
|
||||
cameraSelfView = _eisc.GetBool(JoinMap.CameraSelfView.JoinNumber),
|
||||
cameraSupportsAutoMode = _eisc.GetBool(JoinMap.CameraSupportsAutoMode.JoinNumber),
|
||||
cameraSupportsOffMode = _eisc.GetBool(JoinMap.CameraSupportsOffMode.JoinNumber),
|
||||
currentCallString = _eisc.GetString(JoinMap.CurrentCallNumber.JoinNumber),
|
||||
currentDialString = _eisc.GetString(JoinMap.CurrentDialString.JoinNumber),
|
||||
directoryContactSelected = new
|
||||
{
|
||||
name = _eisc.GetString(JoinMap.DirectoryEntrySelectedName.JoinNumber),
|
||||
number = _eisc.GetString(JoinMap.DirectoryEntrySelectedNumber.JoinNumber)
|
||||
},
|
||||
directorySelectedFolderName = _eisc.GetString(JoinMap.DirectorySelectedFolderName.JoinNumber),
|
||||
isInCall = _eisc.GetString(JoinMap.HookState.JoinNumber) == "Connected",
|
||||
hasDirectory = true,
|
||||
hasDirectorySearch = false,
|
||||
hasRecents = !_eisc.BooleanOutput[502].BoolValue,
|
||||
hasCameras = true,
|
||||
showCamerasWhenNotInCall = _eisc.BooleanOutput[503].BoolValue,
|
||||
selectedCamera = GetSelectedCamera(),
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void PostDirectory()
|
||||
{
|
||||
var u = _eisc.GetUshort(JoinMap.DirectoryRowCount.JoinNumber);
|
||||
var items = new List<object>();
|
||||
for (uint i = 0; i < u; i++)
|
||||
{
|
||||
var name = _eisc.GetString(JoinMap.DirectoryEntriesStart.JoinNumber + i);
|
||||
var id = (i + 1).ToString();
|
||||
// is folder or contact?
|
||||
if (name.StartsWith("[+]"))
|
||||
{
|
||||
items.Add(new
|
||||
{
|
||||
folderId = id,
|
||||
name
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
items.Add(new
|
||||
{
|
||||
contactId = id,
|
||||
name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var directoryMessage = new
|
||||
{
|
||||
currentDirectory = new
|
||||
{
|
||||
isRootDirectory = _eisc.GetBool(JoinMap.DirectoryIsRoot.JoinNumber),
|
||||
directoryResults = items
|
||||
}
|
||||
};
|
||||
PostStatusMessage(JToken.FromObject(directoryMessage));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void PostCameraMode()
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
cameraMode = GetCameraMode()
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private string GetCameraMode()
|
||||
{
|
||||
string m;
|
||||
if (_eisc.GetBool(JoinMap.CameraModeAuto.JoinNumber)) m = eCameraControlMode.Auto.ToString().ToLower();
|
||||
else if (_eisc.GetBool(JoinMap.CameraModeManual.JoinNumber))
|
||||
m = eCameraControlMode.Manual.ToString().ToLower();
|
||||
else m = eCameraControlMode.Off.ToString().ToLower();
|
||||
return m;
|
||||
}
|
||||
|
||||
private void PostSelectedCamera()
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
selectedCamera = GetSelectedCamera()
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private string GetSelectedCamera()
|
||||
{
|
||||
var num = _eisc.GetUshort(JoinMap.CameraNumberSelect.JoinNumber);
|
||||
string m;
|
||||
if (num == 100)
|
||||
{
|
||||
m = "cameraFar";
|
||||
}
|
||||
else
|
||||
{
|
||||
m = "camera" + num;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void PostIsReady()
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
isReady = true
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void PostCallsList()
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
calls = GetCurrentCallList(),
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
private void SelectCamera(string s)
|
||||
{
|
||||
var cam = s.Substring(6);
|
||||
_eisc.SetUshort(JoinMap.CameraNumberSelect.JoinNumber,
|
||||
(ushort)(cam.ToLower() == "far" ? 100 : ushort.Parse(cam)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns the
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private List<CodecActiveCallItem> GetCurrentCallList()
|
||||
{
|
||||
var list = new List<CodecActiveCallItem>();
|
||||
if (_currentCallItem.Status != eCodecCallStatus.Disconnected)
|
||||
{
|
||||
list.Add(_currentCallItem);
|
||||
}
|
||||
if (_eisc.GetBool(JoinMap.IncomingCall.JoinNumber))
|
||||
{
|
||||
list.Add(_incomingCallItem);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Shades;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class IShadesOpenCloseStopMessenger : MessengerBase
|
||||
{
|
||||
private readonly IShadesOpenCloseStop device;
|
||||
|
||||
public IShadesOpenCloseStopMessenger(string key, IShadesOpenCloseStop shades, string messagePath)
|
||||
: base(key, messagePath, shades as Device)
|
||||
{
|
||||
device = shades;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/shadeUp", (id, content) =>
|
||||
{
|
||||
|
||||
device.Open();
|
||||
|
||||
});
|
||||
|
||||
AddAction("/shadeDown", (id, content) =>
|
||||
{
|
||||
|
||||
device.Close();
|
||||
|
||||
});
|
||||
|
||||
var stopDevice = device;
|
||||
if (stopDevice != null)
|
||||
{
|
||||
AddAction("/stopOrPreset", (id, content) =>
|
||||
{
|
||||
stopDevice.Stop();
|
||||
});
|
||||
}
|
||||
|
||||
if (device is IShadesOpenClosedFeedback feedbackDevice)
|
||||
{
|
||||
feedbackDevice.ShadeIsOpenFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>(ShadeIsOpenFeedback_OutputChange);
|
||||
feedbackDevice.ShadeIsClosedFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>(ShadeIsClosedFeedback_OutputChange);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShadeIsOpenFeedback_OutputChange(object sender, Core.FeedbackEventArgs e)
|
||||
{
|
||||
var state = new ShadeBaseStateMessage
|
||||
{
|
||||
IsOpen = e.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
private void ShadeIsClosedFeedback_OutputChange(object sender, Core.FeedbackEventArgs e)
|
||||
{
|
||||
var state = new ShadeBaseStateMessage
|
||||
{
|
||||
IsClosed = e.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new ShadeBaseStateMessage();
|
||||
|
||||
if (device is IShadesOpenClosedFeedback feedbackDevice)
|
||||
{
|
||||
state.IsOpen = feedbackDevice.ShadeIsOpenFeedback.BoolValue;
|
||||
state.IsClosed = feedbackDevice.ShadeIsClosedFeedback.BoolValue;
|
||||
}
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
public class ShadeBaseStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("middleButtonLabel", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string MiddleButtonLabel { get; set; }
|
||||
|
||||
[JsonProperty("isOpen", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsOpen { get; set; }
|
||||
|
||||
[JsonProperty("isClosed", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsClosed { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Properties to configure a SIMPL Messenger
|
||||
/// </summary>
|
||||
public class SimplMessengerPropertiesConfig : EiscApiPropertiesConfig.ApiDevicePropertiesConfig
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Monitoring;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class SystemMonitorMessenger : MessengerBase
|
||||
{
|
||||
private readonly SystemMonitorController systemMonitor;
|
||||
|
||||
public SystemMonitorMessenger(string key, SystemMonitorController sysMon, string messagePath)
|
||||
: base(key, messagePath, sysMon)
|
||||
{
|
||||
systemMonitor = sysMon ?? throw new ArgumentNullException("sysMon");
|
||||
|
||||
systemMonitor.SystemMonitorPropertiesChanged += SysMon_SystemMonitorPropertiesChanged;
|
||||
|
||||
foreach (var p in systemMonitor.ProgramStatusFeedbackCollection)
|
||||
{
|
||||
p.Value.ProgramInfoChanged += ProgramInfoChanged;
|
||||
}
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s => SendFullStatusMessage(), "SendFullSysMonStatus",
|
||||
"Sends the full System Monitor Status", ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts the program information message
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void ProgramInfoChanged(object sender, ProgramInfoEventArgs e)
|
||||
{
|
||||
if (e.ProgramInfo != null)
|
||||
{
|
||||
//Debug.Console(1, "Posting Status Message: {0}", e.ProgramInfo.ToString());
|
||||
PostStatusMessage(JToken.FromObject(e.ProgramInfo)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts the system monitor properties
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void SysMon_SystemMonitorPropertiesChanged(object sender, EventArgs e)
|
||||
{
|
||||
SendSystemMonitorStatusMessage();
|
||||
}
|
||||
|
||||
private void SendFullStatusMessage()
|
||||
{
|
||||
SendSystemMonitorStatusMessage();
|
||||
|
||||
foreach (var p in systemMonitor.ProgramStatusFeedbackCollection)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(p.Value.ProgramInfo));
|
||||
}
|
||||
}
|
||||
|
||||
private void SendSystemMonitorStatusMessage()
|
||||
{
|
||||
// This takes a while, launch a new thread
|
||||
|
||||
Task.Run(() => PostStatusMessage(JToken.FromObject(new SystemMonitorStateMessage
|
||||
{
|
||||
|
||||
TimeZone = systemMonitor.TimeZoneFeedback.IntValue,
|
||||
TimeZoneName = systemMonitor.TimeZoneTextFeedback.StringValue,
|
||||
IoControllerVersion = systemMonitor.IoControllerVersionFeedback.StringValue,
|
||||
SnmpVersion = systemMonitor.SnmpVersionFeedback.StringValue,
|
||||
BacnetVersion = systemMonitor.BaCnetAppVersionFeedback.StringValue,
|
||||
ControllerVersion = systemMonitor.ControllerVersionFeedback.StringValue
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatusMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public class SystemMonitorStateMessage
|
||||
{
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int TimeZone { get; set; }
|
||||
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string TimeZoneName { get; set; }
|
||||
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string IoControllerVersion { get; set; }
|
||||
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string SnmpVersion { get; set; }
|
||||
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string BacnetVersion { get; set; }
|
||||
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string ControllerVersion { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Displays;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class TwoWayDisplayBaseMessenger : MessengerBase
|
||||
{
|
||||
private readonly TwoWayDisplayBase _display;
|
||||
|
||||
public TwoWayDisplayBaseMessenger(string key, string messagePath) : base(key, messagePath)
|
||||
{
|
||||
}
|
||||
|
||||
public TwoWayDisplayBaseMessenger(string key, string messagePath, TwoWayDisplayBase display)
|
||||
: this(key, messagePath)
|
||||
{
|
||||
_display = display;
|
||||
}
|
||||
|
||||
#region Overrides of MessengerBase
|
||||
|
||||
public void SendFullStatus()
|
||||
{
|
||||
var messageObj = new TwoWayDisplayBaseStateMessage
|
||||
{
|
||||
//PowerState = _display.PowerIsOnFeedback.BoolValue,
|
||||
CurrentInput = _display.CurrentInputFeedback.StringValue
|
||||
};
|
||||
|
||||
PostStatusMessage(messageObj);
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
//_display.PowerIsOnFeedback.OutputChange += PowerIsOnFeedbackOnOutputChange;
|
||||
_display.CurrentInputFeedback.OutputChange += CurrentInputFeedbackOnOutputChange;
|
||||
_display.IsCoolingDownFeedback.OutputChange += IsCoolingFeedbackOnOutputChange;
|
||||
_display.IsWarmingUpFeedback.OutputChange += IsWarmingFeedbackOnOutputChange;
|
||||
}
|
||||
|
||||
private void CurrentInputFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
currentInput = feedbackEventArgs.StringValue
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//private void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
//{
|
||||
// PostStatusMessage(JToken.FromObject(new
|
||||
// {
|
||||
// powerState = feedbackEventArgs.BoolValue
|
||||
// })
|
||||
// );
|
||||
//}
|
||||
|
||||
private void IsWarmingFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
isWarming = feedbackEventArgs.BoolValue
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private void IsCoolingFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
isCooling = feedbackEventArgs.BoolValue
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class TwoWayDisplayBaseStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
//[JsonProperty("powerState", NullValueHandling = NullValueHandling.Ignore)]
|
||||
//public bool? PowerState { get; set; }
|
||||
|
||||
[JsonProperty("currentInput", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CurrentInput { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,999 +0,0 @@
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static PepperDash.Essentials.AppServer.Messengers.VideoCodecBaseStateMessage.CameraStatus;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a messaging bridge for a VideoCodecBase device
|
||||
/// </summary>
|
||||
public class VideoCodecBaseMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected VideoCodecBase Codec { get; private set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="codec"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
public VideoCodecBaseMessenger(string key, VideoCodecBase codec, string messagePath)
|
||||
: base(key, messagePath, codec)
|
||||
{
|
||||
Codec = codec ?? throw new ArgumentNullException("codec");
|
||||
codec.CallStatusChange += Codec_CallStatusChange;
|
||||
codec.IsReadyChange += Codec_IsReadyChange;
|
||||
|
||||
if (codec is IHasDirectory dirCodec)
|
||||
{
|
||||
dirCodec.DirectoryResultReturned += DirCodec_DirectoryResultReturned;
|
||||
}
|
||||
|
||||
if (codec is IHasCallHistory recCodec)
|
||||
{
|
||||
recCodec.CallHistory.RecentCallsListHasChanged += CallHistory_RecentCallsListHasChanged;
|
||||
}
|
||||
|
||||
if (codec is IPasswordPrompt pwPromptCodec)
|
||||
{
|
||||
pwPromptCodec.PasswordRequired += OnPasswordRequired;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPasswordRequired(object sender, PasswordPromptEventArgs args)
|
||||
{
|
||||
var eventMsg = new PasswordPromptEventMessage
|
||||
{
|
||||
Message = args.Message,
|
||||
LastAttemptWasIncorrect = args.LastAttemptWasIncorrect,
|
||||
LoginAttemptFailed = args.LoginAttemptFailed,
|
||||
LoginAttemptCancelled = args.LoginAttemptCancelled,
|
||||
EventType = "passwordPrompt"
|
||||
};
|
||||
|
||||
PostEventMessage(eventMsg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void CallHistory_RecentCallsListHasChanged(object sender, EventArgs e)
|
||||
{
|
||||
var state = new VideoCodecBaseStateMessage();
|
||||
|
||||
if (!(sender is CodecCallHistory codecCallHistory)) return;
|
||||
var recents = codecCallHistory.RecentCalls;
|
||||
|
||||
if (recents != null)
|
||||
{
|
||||
state.RecentCalls = recents;
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void DirCodec_DirectoryResultReturned(object sender, DirectoryEventArgs e)
|
||||
{
|
||||
if (Codec is IHasDirectory)
|
||||
SendDirectory(e.Directory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts the current directory
|
||||
/// </summary>
|
||||
protected void SendDirectory(CodecDirectory directory)
|
||||
{
|
||||
var state = new VideoCodecBaseStateMessage();
|
||||
|
||||
|
||||
if (Codec is IHasDirectory dirCodec)
|
||||
{
|
||||
this.LogVerbose("Sending Directory. Directory Item Count: {directoryItemCount}", directory.CurrentDirectoryResults.Count);
|
||||
|
||||
//state.CurrentDirectory = PrefixDirectoryFolderItems(directory);
|
||||
state.CurrentDirectory = directory;
|
||||
CrestronInvoke.BeginInvoke((o) => PostStatusMessage(state));
|
||||
|
||||
/* var directoryMessage = new
|
||||
{
|
||||
currentDirectory = new
|
||||
{
|
||||
directoryResults = prefixedDirectoryResults,
|
||||
isRootDirectory = isRoot
|
||||
}
|
||||
};
|
||||
|
||||
//Spool up a thread in case this is a large quantity of data
|
||||
CrestronInvoke.BeginInvoke((o) => PostStatusMessage(directoryMessage)); */
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void Codec_IsReadyChange(object sender, EventArgs e)
|
||||
{
|
||||
var state = new VideoCodecBaseStateMessage
|
||||
{
|
||||
IsReady = true
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
|
||||
SendFullStatus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called from base's RegisterWithAppServer method
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
try
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/isReady", (id, content) => SendIsReady());
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/dial", (id, content) =>
|
||||
{
|
||||
var value = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
Codec.Dial(value.Value);
|
||||
});
|
||||
|
||||
AddAction("/dialMeeting", (id, content) => Codec.Dial(content.ToObject<Meeting>()));
|
||||
|
||||
AddAction("/endCallById", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
var call = GetCallWithId(s.Value);
|
||||
if (call != null)
|
||||
Codec.EndCall(call);
|
||||
});
|
||||
|
||||
AddAction("/endAllCalls", (id, content) => Codec.EndAllCalls());
|
||||
|
||||
AddAction("/dtmf", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
Codec.SendDtmf(s.Value);
|
||||
});
|
||||
|
||||
AddAction("/rejectById", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var call = GetCallWithId(s.Value);
|
||||
if (call != null)
|
||||
Codec.RejectCall(call);
|
||||
});
|
||||
|
||||
AddAction("/acceptById", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var call = GetCallWithId(s.Value);
|
||||
if (call != null)
|
||||
Codec.AcceptCall(call);
|
||||
});
|
||||
|
||||
Codec.SharingContentIsOnFeedback.OutputChange += SharingContentIsOnFeedback_OutputChange;
|
||||
Codec.SharingSourceFeedback.OutputChange += SharingSourceFeedback_OutputChange;
|
||||
|
||||
// Directory actions
|
||||
if (Codec is IHasDirectory dirCodec)
|
||||
{
|
||||
AddAction("/getDirectory", (id, content) => GetDirectoryRoot());
|
||||
|
||||
AddAction("/directoryById", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
GetDirectory(msg.Value);
|
||||
});
|
||||
|
||||
AddAction("/directorySearch", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
GetDirectory(msg.Value);
|
||||
});
|
||||
|
||||
AddAction("/directoryBack", (id, content) => GetPreviousDirectory());
|
||||
|
||||
dirCodec.PhonebookSyncState.InitialSyncCompleted += PhonebookSyncState_InitialSyncCompleted;
|
||||
}
|
||||
|
||||
// History actions
|
||||
if (Codec is IHasCallHistory recCodec)
|
||||
{
|
||||
AddAction("/getCallHistory", (id, content) => PostCallHistory());
|
||||
}
|
||||
if (Codec is IHasCodecCameras cameraCodec)
|
||||
{
|
||||
this.LogVerbose("Adding IHasCodecCameras Actions");
|
||||
|
||||
cameraCodec.CameraSelected += CameraCodec_CameraSelected;
|
||||
|
||||
AddAction("/cameraSelect", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
cameraCodec.SelectCamera(msg.Value);
|
||||
});
|
||||
|
||||
|
||||
MapCameraActions();
|
||||
|
||||
if (Codec is IHasCodecRoomPresets presetsCodec)
|
||||
{
|
||||
this.LogVerbose("Adding IHasCodecRoomPresets Actions");
|
||||
|
||||
presetsCodec.CodecRoomPresetsListHasChanged += PresetsCodec_CameraPresetsListHasChanged;
|
||||
|
||||
AddAction("/cameraPreset", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<int>>();
|
||||
|
||||
presetsCodec.CodecRoomPresetSelect(msg.Value);
|
||||
});
|
||||
|
||||
AddAction("/cameraPresetStore", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<CodecRoomPreset>();
|
||||
|
||||
presetsCodec.CodecRoomPresetStore(msg.ID, msg.Description);
|
||||
});
|
||||
}
|
||||
|
||||
if (Codec is IHasCameraAutoMode speakerTrackCodec)
|
||||
{
|
||||
this.LogVerbose("Adding IHasCameraAutoMode Actions");
|
||||
|
||||
speakerTrackCodec.CameraAutoModeIsOnFeedback.OutputChange += CameraAutoModeIsOnFeedback_OutputChange;
|
||||
|
||||
AddAction("/cameraModeAuto", (id, content) => speakerTrackCodec.CameraAutoModeOn());
|
||||
|
||||
AddAction("/cameraModeManual", (id, content) => speakerTrackCodec.CameraAutoModeOff());
|
||||
}
|
||||
|
||||
if (Codec is IHasCameraOff cameraOffCodec)
|
||||
{
|
||||
this.LogVerbose("Adding IHasCameraOff Actions");
|
||||
|
||||
cameraOffCodec.CameraIsOffFeedback.OutputChange += (CameraIsOffFeedback_OutputChange);
|
||||
|
||||
AddAction("/cameraModeOff", (id, content) => cameraOffCodec.CameraOff());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (Codec is IHasCodecSelfView selfViewCodec)
|
||||
{
|
||||
this.LogVerbose("Adding IHasCodecSelfView Actions");
|
||||
|
||||
AddAction("/cameraSelfView", (id, content) => selfViewCodec.SelfViewModeToggle());
|
||||
|
||||
selfViewCodec.SelfviewIsOnFeedback.OutputChange += new EventHandler<FeedbackEventArgs>(SelfviewIsOnFeedback_OutputChange);
|
||||
}
|
||||
|
||||
|
||||
if (Codec is IHasCodecLayouts layoutsCodec)
|
||||
{
|
||||
this.LogVerbose("Adding IHasCodecLayouts Actions");
|
||||
|
||||
AddAction("/cameraRemoteView", (id, content) => layoutsCodec.LocalLayoutToggle());
|
||||
|
||||
AddAction("/cameraLayout", (id, content) => layoutsCodec.LocalLayoutToggle());
|
||||
}
|
||||
|
||||
if (Codec is IPasswordPrompt pwCodec)
|
||||
{
|
||||
this.LogVerbose("Adding IPasswordPrompt Actions");
|
||||
|
||||
AddAction("/password", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
pwCodec.SubmitPassword(msg.Value);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (Codec is IHasFarEndContentStatus farEndContentStatus)
|
||||
{
|
||||
farEndContentStatus.ReceivingContent.OutputChange +=
|
||||
(sender, args) => PostReceivingContent(args.BoolValue);
|
||||
}
|
||||
|
||||
this.LogVerbose("Adding Privacy & Standby Actions");
|
||||
|
||||
AddAction("/privacyModeOn", (id, content) => Codec.PrivacyModeOn());
|
||||
AddAction("/privacyModeOff", (id, content) => Codec.PrivacyModeOff());
|
||||
AddAction("/privacyModeToggle", (id, content) => Codec.PrivacyModeToggle());
|
||||
AddAction("/sharingStart", (id, content) => Codec.StartSharing());
|
||||
AddAction("/sharingStop", (id, content) => Codec.StopSharing());
|
||||
AddAction("/standbyOn", (id, content) => Codec.StandbyActivate());
|
||||
AddAction("/standbyOff", (id, content) => Codec.StandbyDeactivate());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.LogException(e, "Exception adding paths");
|
||||
}
|
||||
}
|
||||
|
||||
private void SharingSourceFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
var state = new VideoCodecBaseStateMessage
|
||||
{
|
||||
SharingSource = e.StringValue
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
private void SharingContentIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
var state = new VideoCodecBaseStateMessage
|
||||
{
|
||||
SharingContentIsOn = e.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
private void PhonebookSyncState_InitialSyncCompleted(object sender, EventArgs e)
|
||||
{
|
||||
var state = new VideoCodecBaseStateMessage
|
||||
{
|
||||
InitialPhonebookSyncComplete = true
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
private void CameraIsOffFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
PostCameraMode();
|
||||
}
|
||||
|
||||
private void SelfviewIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
PostCameraSelfView();
|
||||
}
|
||||
|
||||
private void PresetsCodec_CameraPresetsListHasChanged(object sender, EventArgs e)
|
||||
{
|
||||
PostCameraPresets();
|
||||
}
|
||||
|
||||
private void CameraAutoModeIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
PostCameraMode();
|
||||
}
|
||||
|
||||
|
||||
private void CameraCodec_CameraSelected(object sender, CameraSelectedEventArgs e)
|
||||
{
|
||||
MapCameraActions();
|
||||
PostSelectedCamera();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps the camera control actions to the current selected camera on the codec
|
||||
/// </summary>
|
||||
private void MapCameraActions()
|
||||
{
|
||||
if (Codec is IHasCameras cameraCodec && cameraCodec.SelectedCamera != null)
|
||||
{
|
||||
RemoveAction("/cameraUp");
|
||||
RemoveAction("/cameraDown");
|
||||
RemoveAction("/cameraLeft");
|
||||
RemoveAction("/cameraRight");
|
||||
RemoveAction("/cameraZoomIn");
|
||||
RemoveAction("/cameraZoomOut");
|
||||
RemoveAction("/cameraHome");
|
||||
|
||||
if (cameraCodec.SelectedCamera is IHasCameraPtzControl camera)
|
||||
{
|
||||
AddAction("/cameraUp", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
camera.TiltUp();
|
||||
return;
|
||||
}
|
||||
|
||||
camera.TiltStop();
|
||||
}));
|
||||
|
||||
AddAction("/cameraDown", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
camera.TiltDown();
|
||||
return;
|
||||
}
|
||||
|
||||
camera.TiltStop();
|
||||
}));
|
||||
|
||||
AddAction("/cameraLeft", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
camera.PanLeft();
|
||||
return;
|
||||
}
|
||||
|
||||
camera.PanStop();
|
||||
}));
|
||||
|
||||
AddAction("/cameraRight", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
camera.PanRight();
|
||||
return;
|
||||
}
|
||||
|
||||
camera.PanStop();
|
||||
}));
|
||||
|
||||
AddAction("/cameraZoomIn", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
camera.ZoomIn();
|
||||
return;
|
||||
}
|
||||
|
||||
camera.ZoomStop();
|
||||
}));
|
||||
|
||||
AddAction("/cameraZoomOut", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
camera.ZoomOut();
|
||||
return;
|
||||
}
|
||||
|
||||
camera.ZoomStop();
|
||||
}));
|
||||
AddAction("/cameraHome", (id, content) => camera.PositionHome());
|
||||
|
||||
|
||||
RemoveAction("/cameraAutoFocus");
|
||||
RemoveAction("/cameraFocusNear");
|
||||
RemoveAction("/cameraFocusFar");
|
||||
|
||||
if (cameraCodec is IHasCameraFocusControl focusCamera)
|
||||
{
|
||||
AddAction("/cameraAutoFocus", (id, content) => focusCamera.TriggerAutoFocus());
|
||||
|
||||
AddAction("/cameraFocusNear", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
focusCamera.FocusNear();
|
||||
return;
|
||||
}
|
||||
|
||||
focusCamera.FocusStop();
|
||||
}));
|
||||
|
||||
AddAction("/cameraFocusFar", (id, content) => HandleCameraPressAndHold(content, (b) =>
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
focusCamera.FocusFar();
|
||||
return;
|
||||
}
|
||||
|
||||
focusCamera.FocusStop();
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleCameraPressAndHold(JToken content, Action<bool> cameraAction)
|
||||
{
|
||||
var state = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value);
|
||||
if (timerHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
timerHandler(state.Value, cameraAction);
|
||||
|
||||
cameraAction(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
private string GetCameraMode()
|
||||
{
|
||||
string m = "";
|
||||
|
||||
if (Codec is IHasCameraAutoMode speakerTrackCodec)
|
||||
{
|
||||
m = speakerTrackCodec.CameraAutoModeIsOnFeedback.BoolValue
|
||||
? eCameraControlMode.Auto.ToString().ToLower()
|
||||
: eCameraControlMode.Manual.ToString().ToLower();
|
||||
}
|
||||
|
||||
if (Codec is IHasCameraOff cameraOffCodec)
|
||||
{
|
||||
if (cameraOffCodec.CameraIsOffFeedback.BoolValue)
|
||||
m = eCameraControlMode.Off.ToString().ToLower();
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
private void PostCallHistory()
|
||||
{
|
||||
var codec = (Codec as IHasCallHistory);
|
||||
|
||||
if (codec != null)
|
||||
{
|
||||
var status = new VideoCodecBaseStateMessage();
|
||||
|
||||
var recents = codec.CallHistory.RecentCalls;
|
||||
|
||||
if (recents != null)
|
||||
{
|
||||
status.RecentCalls = codec.CallHistory.RecentCalls;
|
||||
|
||||
PostStatusMessage(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to grab a call with string ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
private CodecActiveCallItem GetCallWithId(string id)
|
||||
{
|
||||
return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
private void GetDirectory(string id)
|
||||
{
|
||||
if (!(Codec is IHasDirectory dirCodec))
|
||||
{
|
||||
return;
|
||||
}
|
||||
dirCodec.GetDirectoryFolderContents(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void GetDirectoryRoot()
|
||||
{
|
||||
if (!(Codec is IHasDirectory dirCodec))
|
||||
{
|
||||
// do something else?
|
||||
return;
|
||||
}
|
||||
if (!dirCodec.PhonebookSyncState.InitialSyncComplete)
|
||||
{
|
||||
var state = new VideoCodecBaseStateMessage
|
||||
{
|
||||
InitialPhonebookSyncComplete = false
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
return;
|
||||
}
|
||||
|
||||
dirCodec.SetCurrentDirectoryToRoot();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the parent folder contents
|
||||
/// </summary>
|
||||
private void GetPreviousDirectory()
|
||||
{
|
||||
if (!(Codec is IHasDirectory dirCodec))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dirCodec.GetDirectoryParentFolderContents();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for codec changes
|
||||
/// </summary>
|
||||
private void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
|
||||
{
|
||||
SendFullStatus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void SendIsReady()
|
||||
{
|
||||
var status = new VideoCodecBaseStateMessage();
|
||||
|
||||
var codecType = Codec.GetType();
|
||||
|
||||
status.IsReady = Codec.IsReady;
|
||||
status.IsZoomRoom = codecType.GetInterface("IHasZoomRoomLayouts") != null;
|
||||
|
||||
PostStatusMessage(status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to build call status for vtc
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected VideoCodecBaseStateMessage GetStatus()
|
||||
{
|
||||
var status = new VideoCodecBaseStateMessage();
|
||||
|
||||
|
||||
if (Codec is IHasCodecCameras camerasCodec)
|
||||
{
|
||||
status.Cameras = new VideoCodecBaseStateMessage.CameraStatus
|
||||
{
|
||||
CameraManualIsSupported = true,
|
||||
CameraAutoIsSupported = Codec.SupportsCameraAutoMode,
|
||||
CameraOffIsSupported = Codec.SupportsCameraOff,
|
||||
CameraMode = GetCameraMode(),
|
||||
Cameras = camerasCodec.Cameras,
|
||||
SelectedCamera = GetSelectedCamera(camerasCodec)
|
||||
};
|
||||
}
|
||||
|
||||
if (Codec is IHasDirectory directoryCodec)
|
||||
{
|
||||
status.HasDirectory = true;
|
||||
status.HasDirectorySearch = true;
|
||||
status.CurrentDirectory = directoryCodec.CurrentDirectoryResult;
|
||||
}
|
||||
|
||||
var codecType = Codec.GetType();
|
||||
|
||||
status.CameraSelfViewIsOn = Codec is IHasCodecSelfView && (Codec as IHasCodecSelfView).SelfviewIsOnFeedback.BoolValue;
|
||||
status.IsInCall = Codec.IsInCall;
|
||||
status.PrivacyModeIsOn = Codec.PrivacyModeIsOnFeedback.BoolValue;
|
||||
status.SharingContentIsOn = Codec.SharingContentIsOnFeedback.BoolValue;
|
||||
status.SharingSource = Codec.SharingSourceFeedback.StringValue;
|
||||
status.StandbyIsOn = Codec.StandbyIsOnFeedback.BoolValue;
|
||||
status.Calls = Codec.ActiveCalls;
|
||||
status.Info = Codec.CodecInfo;
|
||||
status.ShowSelfViewByDefault = Codec.ShowSelfViewByDefault;
|
||||
status.SupportsAdHocMeeting = Codec is IHasStartMeeting;
|
||||
status.HasRecents = Codec is IHasCallHistory;
|
||||
status.HasCameras = Codec is IHasCameras;
|
||||
status.Presets = GetCurrentPresets();
|
||||
status.IsZoomRoom = codecType.GetInterface("IHasZoomRoomLayouts") != null;
|
||||
status.ReceivingContent = Codec is IHasFarEndContentStatus && (Codec as IHasFarEndContentStatus).ReceivingContent.BoolValue;
|
||||
|
||||
if (Codec is IHasMeetingInfo meetingInfoCodec)
|
||||
{
|
||||
status.MeetingInfo = meetingInfoCodec.MeetingInfo;
|
||||
}
|
||||
|
||||
//Debug.Console(2, this, "VideoCodecBaseStatus:\n{0}", JsonConvert.SerializeObject(status));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
protected virtual void SendFullStatus()
|
||||
{
|
||||
if (!Codec.IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CrestronInvoke.BeginInvoke((o) => PostStatusMessage(GetStatus()));
|
||||
}
|
||||
|
||||
private void PostReceivingContent(bool receivingContent)
|
||||
{
|
||||
var state = new VideoCodecBaseStateMessage
|
||||
{
|
||||
ReceivingContent = receivingContent
|
||||
};
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
private void PostCameraSelfView()
|
||||
{
|
||||
var status = new VideoCodecBaseStateMessage
|
||||
{
|
||||
CameraSelfViewIsOn = Codec is IHasCodecSelfView
|
||||
&& (Codec as IHasCodecSelfView).SelfviewIsOnFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void PostCameraMode()
|
||||
{
|
||||
var status = new VideoCodecBaseStateMessage
|
||||
{
|
||||
CameraMode = GetCameraMode()
|
||||
};
|
||||
|
||||
PostStatusMessage(status);
|
||||
}
|
||||
|
||||
private void PostSelectedCamera()
|
||||
{
|
||||
var camerasCodec = Codec as IHasCodecCameras;
|
||||
|
||||
var status = new VideoCodecBaseStateMessage
|
||||
{
|
||||
Cameras = new VideoCodecBaseStateMessage.CameraStatus() { SelectedCamera = GetSelectedCamera(camerasCodec) },
|
||||
Presets = GetCurrentPresets()
|
||||
};
|
||||
PostStatusMessage(status);
|
||||
}
|
||||
|
||||
private void PostCameraPresets()
|
||||
{
|
||||
var status = new VideoCodecBaseStateMessage
|
||||
{
|
||||
Presets = GetCurrentPresets()
|
||||
};
|
||||
|
||||
PostStatusMessage(status);
|
||||
}
|
||||
|
||||
private Camera GetSelectedCamera(IHasCodecCameras camerasCodec)
|
||||
{
|
||||
var camera = new Camera();
|
||||
|
||||
if (camerasCodec.SelectedCameraFeedback != null)
|
||||
camera.Key = camerasCodec.SelectedCameraFeedback.StringValue;
|
||||
if (camerasCodec.SelectedCamera != null)
|
||||
{
|
||||
camera.Name = camerasCodec.SelectedCamera.Name;
|
||||
|
||||
camera.Capabilities = new Camera.CameraCapabilities()
|
||||
{
|
||||
CanPan = camerasCodec.SelectedCamera.CanPan,
|
||||
CanTilt = camerasCodec.SelectedCamera.CanTilt,
|
||||
CanZoom = camerasCodec.SelectedCamera.CanZoom,
|
||||
CanFocus = camerasCodec.SelectedCamera.CanFocus,
|
||||
};
|
||||
}
|
||||
|
||||
if (camerasCodec.ControllingFarEndCameraFeedback != null)
|
||||
camera.IsFarEnd = camerasCodec.ControllingFarEndCameraFeedback.BoolValue;
|
||||
|
||||
|
||||
return camera;
|
||||
}
|
||||
|
||||
private List<CodecRoomPreset> GetCurrentPresets()
|
||||
{
|
||||
var presetsCodec = Codec as IHasCodecRoomPresets;
|
||||
|
||||
List<CodecRoomPreset> currentPresets = null;
|
||||
|
||||
if (presetsCodec != null && Codec is IHasFarEndCameraControl &&
|
||||
(Codec as IHasFarEndCameraControl).ControllingFarEndCameraFeedback.BoolValue)
|
||||
currentPresets = presetsCodec.FarEndRoomPresets;
|
||||
else if (presetsCodec != null) currentPresets = presetsCodec.NearEndPresets;
|
||||
|
||||
return currentPresets;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A class that represents the state data to be sent to the user app
|
||||
/// </summary>
|
||||
public class VideoCodecBaseStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
|
||||
[JsonProperty("calls", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<CodecActiveCallItem> Calls { get; set; }
|
||||
|
||||
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CameraMode { get; set; }
|
||||
|
||||
[JsonProperty("cameraSelfView", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraSelfViewIsOn { get; set; }
|
||||
|
||||
[JsonProperty("cameras", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CameraStatus Cameras { get; set; }
|
||||
|
||||
[JsonProperty("cameraSupportsAutoMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraSupportsAutoMode { get; set; }
|
||||
|
||||
[JsonProperty("cameraSupportsOffMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraSupportsOffMode { get; set; }
|
||||
|
||||
[JsonProperty("currentDialString", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CurrentDialString { get; set; }
|
||||
|
||||
[JsonProperty("currentDirectory", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CodecDirectory CurrentDirectory { get; set; }
|
||||
|
||||
[JsonProperty("directorySelectedFolderName", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string DirectorySelectedFolderName { get; set; }
|
||||
|
||||
[JsonProperty("hasCameras", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasCameras { get; set; }
|
||||
|
||||
[JsonProperty("hasDirectory", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasDirectory { get; set; }
|
||||
|
||||
[JsonProperty("hasDirectorySearch", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasDirectorySearch { get; set; }
|
||||
|
||||
[JsonProperty("hasPresets", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasPresets { get; set; }
|
||||
|
||||
[JsonProperty("hasRecents", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasRecents { get; set; }
|
||||
|
||||
[JsonProperty("initialPhonebookSyncComplete", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? InitialPhonebookSyncComplete { get; set; }
|
||||
|
||||
[JsonProperty("info", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public VideoCodecInfo Info { get; set; }
|
||||
|
||||
[JsonProperty("isInCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsInCall { get; set; }
|
||||
|
||||
[JsonProperty("isReady", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsReady { get; set; }
|
||||
|
||||
[JsonProperty("isZoomRoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsZoomRoom { get; set; }
|
||||
|
||||
[JsonProperty("meetingInfo", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public MeetingInfo MeetingInfo { get; set; }
|
||||
|
||||
[JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<CodecRoomPreset> Presets { get; set; }
|
||||
|
||||
[JsonProperty("privacyModeIsOn", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? PrivacyModeIsOn { get; set; }
|
||||
|
||||
[JsonProperty("receivingContent", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? ReceivingContent { get; set; }
|
||||
|
||||
[JsonProperty("recentCalls", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<CodecCallHistory.CallHistoryEntry> RecentCalls { get; set; }
|
||||
|
||||
[JsonProperty("sharingContentIsOn", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? SharingContentIsOn { get; set; }
|
||||
|
||||
[JsonProperty("sharingSource", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string SharingSource { get; set; }
|
||||
|
||||
[JsonProperty("showCamerasWhenNotInCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? ShowCamerasWhenNotInCall { get; set; }
|
||||
|
||||
[JsonProperty("showSelfViewByDefault", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? ShowSelfViewByDefault { get; set; }
|
||||
|
||||
[JsonProperty("standbyIsOn", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? StandbyIsOn { get; set; }
|
||||
|
||||
[JsonProperty("supportsAdHocMeeting", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? SupportsAdHocMeeting { get; set; }
|
||||
|
||||
public class CameraStatus
|
||||
{
|
||||
[JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraManualIsSupported { get; set; }
|
||||
|
||||
[JsonProperty("cameraAutoSupported", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraAutoIsSupported { get; set; }
|
||||
|
||||
[JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraOffIsSupported { get; set; }
|
||||
|
||||
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CameraMode { get; set; }
|
||||
|
||||
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<CameraBase> Cameras { get; set; }
|
||||
|
||||
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Camera SelectedCamera { get; set; }
|
||||
|
||||
public class Camera
|
||||
{
|
||||
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsFarEnd { get; set; }
|
||||
|
||||
[JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CameraCapabilities Capabilities { get; set; }
|
||||
|
||||
public class CameraCapabilities
|
||||
{
|
||||
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CanPan { get; set; }
|
||||
|
||||
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CanTilt { get; set; }
|
||||
|
||||
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CanZoom { get; set; }
|
||||
|
||||
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CanFocus { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class VideoCodecBaseEventMessage : DeviceEventMessageBase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class PasswordPromptEventMessage : VideoCodecBaseEventMessage
|
||||
{
|
||||
[JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Message { get; set; }
|
||||
[JsonProperty("lastAttemptWasIncorrect", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool LastAttemptWasIncorrect { get; set; }
|
||||
|
||||
[JsonProperty("loginAttemptFailed", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool LoginAttemptFailed { get; set; }
|
||||
|
||||
[JsonProperty("loginAttemptCancelled", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool LoginAttemptCancelled { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
public class MobileControlMessage : IMobileControlMessage
|
||||
{
|
||||
[JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[JsonProperty("clientId")]
|
||||
public string ClientId { get; set; }
|
||||
|
||||
[JsonProperty("content")]
|
||||
public JToken Content { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer
|
||||
{
|
||||
public class MobileControlSimpleContent<T>
|
||||
{
|
||||
[JsonProperty("value", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public T Value { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ProjectType>ProgramLibrary</ProjectType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RootNamespace>PepperDash.Essentials.AppServer</RootNamespace>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyTitle>mobile-control-messengers</AssemblyTitle>
|
||||
<AssemblyName>mobile-control-messengers</AssemblyName>
|
||||
<Product>mobile-control-messengers</Product>
|
||||
<Copyright>Copyright © 2024</Copyright>
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
<InformationalVersion>$(Version)</InformationalVersion>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Authors>PepperDash Technology</Authors>
|
||||
<PackageId>PepperDash.Essentials.MobileControl.Messengers</PackageId>
|
||||
<PackageTags>crestron 4series</PackageTags>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
<DefineConstants>$(DefineConstants);SERIES4</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DefineConstants>$(DefineConstants);SERIES4</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="Messengers\SIMPLAtcMessenger.cs" />
|
||||
<Compile Remove="Messengers\SIMPLCameraMessenger.cs" />
|
||||
<Compile Remove="Messengers\SIMPLDirectRouteMessenger.cs" />
|
||||
<Compile Remove="Messengers\SimplMessengerPropertiesConfig.cs" />
|
||||
<Compile Remove="Messengers\SIMPLRouteMessenger.cs" />
|
||||
<Compile Remove="Messengers\SIMPLVtcMessenger.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" />
|
||||
<PackageReference Include="PepperDashCore" Version="2.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PepperDash.Essentials.Core\PepperDash.Essentials.Core.csproj">
|
||||
<Private>false</Private>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PepperDash.Essentials.Devices.Common\PepperDash.Essentials.Devices.Common.csproj">
|
||||
<Private>false</Private>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,570 +0,0 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.AppServer
|
||||
{
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("QrCodeUrl")]
|
||||
public JoinDataComplete QrCodeUrl =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 403, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "QR Code URL",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("PortalSystemUrl")]
|
||||
public JoinDataComplete PortalSystemUrl =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 404, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Portal System URL",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("MasterVolume")]
|
||||
public JoinDataComplete MasterVolume =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Master Volume Mute Toggle/FB/Level/Label",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.DigitalAnalogSerial
|
||||
});
|
||||
|
||||
[JoinName("VolumeJoinStart")]
|
||||
public JoinDataComplete VolumeJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 8 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Mute Toggle/FB/Level/Label",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.DigitalAnalogSerial
|
||||
});
|
||||
|
||||
[JoinName("PrivacyMute")]
|
||||
public JoinDataComplete PrivacyMute =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Privacy Mute Toggle/FB",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("PromptForCode")]
|
||||
public JoinDataComplete PromptForCode =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Prompt User for Code",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ClientJoined")]
|
||||
public JoinDataComplete ClientJoined =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Client Joined",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ActivityPhoneCallEnable")]
|
||||
public JoinDataComplete ActivityPhoneCallEnable =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 48, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Enable Activity Phone Call",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ActivityVideoCallEnable")]
|
||||
public JoinDataComplete ActivityVideoCallEnable =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 49, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Enable Activity Video Call",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ActivityShare")]
|
||||
public JoinDataComplete ActivityShare =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Activity Share",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ActivityPhoneCall")]
|
||||
public JoinDataComplete ActivityPhoneCall =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Activity Phone Call",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ActivityVideoCall")]
|
||||
public JoinDataComplete ActivityVideoCall =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Activity Video Call",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ShutdownPromptDuration")]
|
||||
public JoinDataComplete ShutdownPromptDuration =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Shutdown Cancel",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("ShutdownCancel")]
|
||||
public JoinDataComplete ShutdownCancel =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Shutdown Cancel",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ShutdownEnd")]
|
||||
public JoinDataComplete ShutdownEnd =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Shutdown End",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ShutdownStart")]
|
||||
public JoinDataComplete ShutdownStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 63, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Shutdown Start",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceHasChanged")]
|
||||
public JoinDataComplete SourceHasChanged =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 71, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source Changed",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CurrentSourceKey")]
|
||||
public JoinDataComplete CurrentSourceKey =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 71, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Key of selected source",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
|
||||
[JoinName("ConfigIsLocal")]
|
||||
public JoinDataComplete ConfigIsLocal =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Config is local to Essentials",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("NumberOfAuxFaders")]
|
||||
public JoinDataComplete NumberOfAuxFaders =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Number of Auxilliary Faders",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("SpeedDialNameStartJoin")]
|
||||
public JoinDataComplete SpeedDialNameStartJoin =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 241, JoinSpan = 10 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Speed Dial names",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("SpeedDialNumberStartJoin")]
|
||||
public JoinDataComplete SpeedDialNumberStartJoin =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 251, JoinSpan = 10 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Speed Dial numbers",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("SpeedDialVisibleStartJoin")]
|
||||
public JoinDataComplete SpeedDialVisibleStartJoin =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 261, JoinSpan = 10 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Speed Dial Visible",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("RoomIsOn")]
|
||||
public JoinDataComplete RoomIsOn =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 301, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Room Is On",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("UserCodeToSystem")]
|
||||
public JoinDataComplete UserCodeToSystem =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 401, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "User Code",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("ServerUrl")]
|
||||
public JoinDataComplete ServerUrl =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 402, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Server URL",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("ConfigRoomName")]
|
||||
public JoinDataComplete ConfigRoomName =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 501, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Room Name",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("ConfigHelpMessage")]
|
||||
public JoinDataComplete ConfigHelpMessage =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 502, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Room help message",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("ConfigHelpNumber")]
|
||||
public JoinDataComplete ConfigHelpNumber =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 503, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Room help number",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("ConfigRoomPhoneNumber")]
|
||||
public JoinDataComplete ConfigRoomPhoneNumber =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 504, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Room phone number",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("ConfigRoomURI")]
|
||||
public JoinDataComplete ConfigRoomUri =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 505, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Room URI",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("ApiOnlineAndAuthorized")]
|
||||
public JoinDataComplete ApiOnlineAndAuthorized =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 500, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Config info from SIMPL is ready",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ConfigIsReady")]
|
||||
public JoinDataComplete ConfigIsReady =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 501, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Config info from SIMPL is ready",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ReadyForConfig")]
|
||||
public JoinDataComplete ReadyForConfig =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 501, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Config info from SIMPL is ready",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("HideVideoConfRecents")]
|
||||
public JoinDataComplete HideVideoConfRecents =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 502, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Hide Video Conference Recents",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ShowCameraWhenNotInCall")]
|
||||
public JoinDataComplete ShowCameraWhenNotInCall =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 503, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Show camera when not in call",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("UseSourceEnabled")]
|
||||
public JoinDataComplete UseSourceEnabled =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 504, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Use Source Enabled Joins",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
|
||||
[JoinName("SourceShareDisableJoinStart")]
|
||||
public JoinDataComplete SourceShareDisableJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 601, JoinSpan = 20 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source is not sharable",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceIsEnabledJoinStart")]
|
||||
public JoinDataComplete SourceIsEnabledJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 621, JoinSpan = 20 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source is enabled/visible",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceIsControllableJoinStart")]
|
||||
public JoinDataComplete SourceIsControllableJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 641, JoinSpan = 20 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source is controllable",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceIsAudioSourceJoinStart")]
|
||||
public JoinDataComplete SourceIsAudioSourceJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 661, JoinSpan = 20 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source is Audio Source",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
|
||||
[JoinName("SourceNameJoinStart")]
|
||||
public JoinDataComplete SourceNameJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 601, JoinSpan = 20 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source Names",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("SourceIconJoinStart")]
|
||||
public JoinDataComplete SourceIconJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 621, JoinSpan = 20 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source Icons",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("SourceKeyJoinStart")]
|
||||
public JoinDataComplete SourceKeyJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 641, JoinSpan = 20 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source Keys",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("SourceControlDeviceKeyJoinStart")]
|
||||
public JoinDataComplete SourceControlDeviceKeyJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 701, JoinSpan = 20 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source Control Device Keys",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("SourceTypeJoinStart")]
|
||||
public JoinDataComplete SourceTypeJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 661, JoinSpan = 20 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source Types",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CameraNearNameStart")]
|
||||
public JoinDataComplete CameraNearNameStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 761, JoinSpan = 10 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Near End Camera Names",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CameraFarName")]
|
||||
public JoinDataComplete CameraFarName =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 771, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Far End Camera Name",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
#region Advanced Sharing
|
||||
[JoinName("SupportsAdvancedSharing")]
|
||||
public JoinDataComplete SupportsAdvancedSharing =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 505, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Supports Advanced Sharing",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("UseDestinationEnable")]
|
||||
public JoinDataComplete UseDestinationEnable =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 506, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Use Destination Enable",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
|
||||
[JoinName("UserCanChangeShareMode")]
|
||||
public JoinDataComplete UserCanChangeShareMode =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 507, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Share Mode Toggle Visible to User",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DestinationNameJoinStart")]
|
||||
public JoinDataComplete DestinationNameJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 801, JoinSpan = 10 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Destination Name",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DestinationDeviceKeyJoinStart")]
|
||||
public JoinDataComplete DestinationDeviceKeyJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 811, JoinSpan = 10 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Destination Device Key",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DestinationTypeJoinStart")]
|
||||
public JoinDataComplete DestinationTypeJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 821, JoinSpan = 10 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Destination type. Should be Audio, Video, AudioVideo",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DestinationIsEnabledJoinStart")]
|
||||
public JoinDataComplete DestinationIsEnabledJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 801, JoinSpan = 10 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Show Destination on UI",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
#endregion
|
||||
|
||||
public MobileControlSIMPLRoomJoinMap(uint joinStart)
|
||||
: base(joinStart, typeof(MobileControlSIMPLRoomJoinMap))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer
|
||||
{
|
||||
public class MobileControlSIMPLRunDirectRouteActionJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("AdvancedSharingModeFb")]
|
||||
public JoinDataComplete AdvancedSharingModeFb =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Use Advanced Sharing Mode",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("AdvancedSharingModeOn")]
|
||||
public JoinDataComplete AdvancedSharingModeOn =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Use Advanced Sharing Mode",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("AdvancedSharingModeOff")]
|
||||
public JoinDataComplete AdvancedSharingModeOff =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Use Advanced Sharing Mode",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("AdvancedSharingModeToggle")]
|
||||
public JoinDataComplete AdvancedSharingModeToggle =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Use Advanced Sharing Mode",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceForDestinationJoinStart")]
|
||||
public JoinDataComplete SourceForDestinationJoinStart =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 10 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source to Route to Destination & FB",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("SourceForDestinationAudio")]
|
||||
public JoinDataComplete SourceForDestinationAudio =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Source to Route to Destination & FB",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
public MobileControlSIMPLRunDirectRouteActionJoinMap(uint joinStart)
|
||||
: base(joinStart, typeof(MobileControlSIMPLRunDirectRouteActionJoinMap))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.AppServer
|
||||
{
|
||||
public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("EndCall")]
|
||||
public JoinDataComplete EndCall =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 21, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Hang Up",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("IncomingAnswer")]
|
||||
public JoinDataComplete IncomingAnswer =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Answer Incoming Call",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("IncomingReject")]
|
||||
public JoinDataComplete IncomingReject =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Reject Incoming Call",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SpeedDialStart")]
|
||||
public JoinDataComplete SpeedDialStart =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 41, JoinSpan = 4 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Speed Dial",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CurrentDialString")]
|
||||
public JoinDataComplete CurrentDialString =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Dial String",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CurrentCallNumber")]
|
||||
public JoinDataComplete CurrentCallNumber =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Call Number",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CurrentCallName")]
|
||||
public JoinDataComplete CurrentCallName =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Call Name",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("HookState")]
|
||||
public JoinDataComplete HookState =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 21, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Hook State",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CallDirection")]
|
||||
public JoinDataComplete CallDirection =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 22, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Call Direction",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("IncomingCallName")]
|
||||
public JoinDataComplete IncomingCallName =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Incoming Call Name",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("IncomingCallNumber")]
|
||||
public JoinDataComplete IncomingCallNumber =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Incoming Call Number",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("0")]
|
||||
public JoinDataComplete Dtmf0 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 10, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 0",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("1")]
|
||||
public JoinDataComplete Dtmf1 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 1",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("2")]
|
||||
public JoinDataComplete Dtmf2 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 2",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("3")]
|
||||
public JoinDataComplete Dtmf3 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 3",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("4")]
|
||||
public JoinDataComplete Dtmf4 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 4",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("5")]
|
||||
public JoinDataComplete Dtmf5 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 5",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("6")]
|
||||
public JoinDataComplete Dtmf6 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 6",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("7")]
|
||||
public JoinDataComplete Dtmf7 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 7",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("8")]
|
||||
public JoinDataComplete Dtmf8 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 8",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("9")]
|
||||
public JoinDataComplete Dtmf9 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 9",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("*")]
|
||||
public JoinDataComplete DtmfStar =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF *",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("#")]
|
||||
public JoinDataComplete DtmfPound =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF #",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that passes the joinStart to the base class
|
||||
/// </summary>
|
||||
/// <param name="joinStart"></param>
|
||||
public SIMPLAtcJoinMap(uint joinStart)
|
||||
: base(joinStart, typeof(SIMPLAtcJoinMap))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,553 +0,0 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.AppServer
|
||||
{
|
||||
public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("EndCall")]
|
||||
public JoinDataComplete EndCall =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 24, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Hang Up",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("IncomingCall")]
|
||||
public JoinDataComplete IncomingCall =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 50, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Incoming Call",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("IncomingAnswer")]
|
||||
public JoinDataComplete IncomingAnswer =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Answer Incoming Call",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("IncomingReject")]
|
||||
public JoinDataComplete IncomingReject =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Reject Incoming Call",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SpeedDialStart")]
|
||||
public JoinDataComplete SpeedDialStart =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 41, JoinSpan = 4 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Speed Dial",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectorySearchBusy")]
|
||||
public JoinDataComplete DirectorySearchBusy =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 100, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Directory Search Busy FB",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectoryLineSelected")]
|
||||
public JoinDataComplete DirectoryLineSelected =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Directory Line Selected FB",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectoryEntryIsContact")]
|
||||
public JoinDataComplete DirectoryEntryIsContact =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Directory Selected Entry Is Contact FB",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectoryIsRoot")]
|
||||
public JoinDataComplete DirectoryIsRoot =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 102, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Directory is on Root FB",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DDirectoryHasChanged")]
|
||||
public JoinDataComplete DDirectoryHasChanged =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 103, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Directory has changed FB",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectoryRoot")]
|
||||
public JoinDataComplete DirectoryRoot =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 104, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Go to Directory Root",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectoryFolderBack")]
|
||||
public JoinDataComplete DirectoryFolderBack =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 105, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Go back one directory level",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectoryDialSelectedLine")]
|
||||
public JoinDataComplete DirectoryDialSelectedLine =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 106, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Dial selected directory line",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraTiltUp")]
|
||||
public JoinDataComplete CameraTiltUp =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 111, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Tilt Up",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraTiltDown")]
|
||||
public JoinDataComplete CameraTiltDown =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 112, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Tilt Down",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraPanLeft")]
|
||||
public JoinDataComplete CameraPanLeft =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 113, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Pan Left",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraPanRight")]
|
||||
public JoinDataComplete CameraPanRight =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 114, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Pan Right",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraZoomIn")]
|
||||
public JoinDataComplete CameraZoomIn =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 115, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Zoom In",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraZoomOut")]
|
||||
public JoinDataComplete CameraZoomOut =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 116, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Zoom Out",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraPresetStart")]
|
||||
public JoinDataComplete CameraPresetStart =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 121, JoinSpan = 5 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Presets",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraModeAuto")]
|
||||
public JoinDataComplete CameraModeAuto =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 131, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Mode Auto",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraModeManual")]
|
||||
public JoinDataComplete CameraModeManual =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 132, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Mode Manual",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraModeOff")]
|
||||
public JoinDataComplete CameraModeOff =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 133, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Mode Off",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraSelfView")]
|
||||
public JoinDataComplete CameraSelfView =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 141, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Self View Toggle/FB",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraLayout")]
|
||||
public JoinDataComplete CameraLayout =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 142, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Layout Toggle",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraSupportsAutoMode")]
|
||||
public JoinDataComplete CameraSupportsAutoMode =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 143, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Supports Auto Mode FB",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraSupportsOffMode")]
|
||||
public JoinDataComplete CameraSupportsOffMode =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 144, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Supports Off Mode FB",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraNumberSelect")]
|
||||
public JoinDataComplete CameraNumberSelect =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 60, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Camera Number Select/FB",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectorySelectRow")]
|
||||
public JoinDataComplete DirectorySelectRow =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Directory Select Row",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("DirectoryRowCount")]
|
||||
public JoinDataComplete DirectoryRowCount =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Directory Row Count FB",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("CurrentDialString")]
|
||||
public JoinDataComplete CurrentDialString =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Dial String",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CurrentCallName")]
|
||||
public JoinDataComplete CurrentCallName =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Call Name",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CurrentCallNumber")]
|
||||
public JoinDataComplete CurrentCallNumber =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Call Number",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("HookState")]
|
||||
public JoinDataComplete HookState =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 31, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Hook State",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CallDirection")]
|
||||
public JoinDataComplete CallDirection =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 22, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Call Direction",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("IncomingCallName")]
|
||||
public JoinDataComplete IncomingCallName =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Incoming Call Name",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("IncomingCallNumber")]
|
||||
public JoinDataComplete IncomingCallNumber =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Incoming Call Number",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DirectorySearchString")]
|
||||
public JoinDataComplete DirectorySearchString =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 100, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Directory Search String",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DirectoryEntriesStart")]
|
||||
public JoinDataComplete DirectoryEntriesStart =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 255 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Directory Entries",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DirectoryEntrySelectedName")]
|
||||
public JoinDataComplete DirectoryEntrySelectedName =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 356, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Selected Directory Entry Name",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DirectoryEntrySelectedNumber")]
|
||||
public JoinDataComplete DirectoryEntrySelectedNumber =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 357, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Selected Directory Entry Number",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DirectorySelectedFolderName")]
|
||||
public JoinDataComplete DirectorySelectedFolderName =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 358, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Selected Directory Folder Name",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("1")]
|
||||
public JoinDataComplete Dtmf1 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 1",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("2")]
|
||||
public JoinDataComplete Dtmf2 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 2",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("3")]
|
||||
public JoinDataComplete Dtmf3 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 3",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("4")]
|
||||
public JoinDataComplete Dtmf4 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 4",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("5")]
|
||||
public JoinDataComplete Dtmf5 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 5",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("6")]
|
||||
public JoinDataComplete Dtmf6 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 6",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("7")]
|
||||
public JoinDataComplete Dtmf7 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 7",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("8")]
|
||||
public JoinDataComplete Dtmf8 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 8",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("9")]
|
||||
public JoinDataComplete Dtmf9 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 9",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("0")]
|
||||
public JoinDataComplete Dtmf0 =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 10, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF 0",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("*")]
|
||||
public JoinDataComplete DtmfStar =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF *",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("#")]
|
||||
public JoinDataComplete DtmfPound =
|
||||
new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 },
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "DTMF #",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
public SIMPLVtcJoinMap(uint joinStart)
|
||||
: base(joinStart, typeof(SIMPLVtcJoinMap))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class AuthorizationResponse
|
||||
{
|
||||
[JsonProperty("authorized")]
|
||||
public bool Authorized { get; set; }
|
||||
|
||||
[JsonProperty("reason", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Reason { get; set; } = null;
|
||||
}
|
||||
|
||||
public class AuthorizationRequest
|
||||
{
|
||||
[JsonProperty("grantCode")]
|
||||
public string GrantCode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a room whose configuration is derived from runtime data,
|
||||
/// perhaps from another program, and that the data may not be fully
|
||||
/// available at startup.
|
||||
/// </summary>
|
||||
public interface IDelayedConfiguration
|
||||
{
|
||||
|
||||
|
||||
event EventHandler<EventArgs> ConfigurationIsReady;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class MobileControlAction : IMobileControlAction
|
||||
{
|
||||
public IMobileControlMessenger Messenger { get; private set; }
|
||||
|
||||
public Action<string, string, JToken> Action { get; private set; }
|
||||
|
||||
public MobileControlAction(IMobileControlMessenger messenger, Action<string, string, JToken> handler)
|
||||
{
|
||||
Messenger = messenger;
|
||||
Action = handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MobileControlConfig
|
||||
{
|
||||
[JsonProperty("serverUrl")]
|
||||
public string ServerUrl { get; set; }
|
||||
|
||||
[JsonProperty("clientAppUrl")]
|
||||
public string ClientAppUrl { get; set; }
|
||||
|
||||
[JsonProperty("directServer")]
|
||||
public MobileControlDirectServerPropertiesConfig DirectServer { get; set; }
|
||||
|
||||
[JsonProperty("applicationConfig")]
|
||||
public MobileControlApplicationConfig ApplicationConfig { get; set; } = null;
|
||||
|
||||
[JsonProperty("enableApiServer")]
|
||||
public bool EnableApiServer { get; set; } = true;
|
||||
}
|
||||
|
||||
public class MobileControlDirectServerPropertiesConfig
|
||||
{
|
||||
[JsonProperty("enableDirectServer")]
|
||||
public bool EnableDirectServer { get; set; }
|
||||
|
||||
[JsonProperty("port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
[JsonProperty("logging")]
|
||||
public MobileControlLoggingConfig Logging { get; set; }
|
||||
|
||||
[JsonProperty("automaticallyForwardPortToCSLAN")]
|
||||
public bool? AutomaticallyForwardPortToCSLAN { get; set; }
|
||||
|
||||
public MobileControlDirectServerPropertiesConfig()
|
||||
{
|
||||
Logging = new MobileControlLoggingConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public class MobileControlLoggingConfig
|
||||
{
|
||||
[JsonProperty("enableRemoteLogging")]
|
||||
public bool EnableRemoteLogging { get; set; }
|
||||
|
||||
[JsonProperty("host")]
|
||||
public string Host { get; set; }
|
||||
|
||||
[JsonProperty("port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class MobileControlRoomBridgePropertiesConfig
|
||||
{
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MobileControlSimplRoomBridgePropertiesConfig
|
||||
{
|
||||
[JsonProperty("eiscId")]
|
||||
public string EiscId { get; set; }
|
||||
}
|
||||
|
||||
public class MobileControlApplicationConfig
|
||||
{
|
||||
[JsonProperty("apiPath")]
|
||||
public string ApiPath { get; set; }
|
||||
|
||||
[JsonProperty("gatewayAppPath")]
|
||||
public string GatewayAppPath { get; set; }
|
||||
|
||||
[JsonProperty("enableDev")]
|
||||
public bool? EnableDev { get; set; }
|
||||
|
||||
[JsonProperty("logoPath")]
|
||||
/// <summary>
|
||||
/// Client logo to be used in header and/or splash screen
|
||||
/// </summary>
|
||||
public string LogoPath { get; set; }
|
||||
|
||||
[JsonProperty("iconSet")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public MCIconSet? IconSet { get; set; }
|
||||
|
||||
[JsonProperty("loginMode")]
|
||||
public string LoginMode { get; set; }
|
||||
|
||||
[JsonProperty("modes")]
|
||||
public Dictionary<string, McMode> Modes { get; set; }
|
||||
|
||||
[JsonProperty("enableRemoteLogging")]
|
||||
public bool Logging { get; set; }
|
||||
|
||||
[JsonProperty("partnerMetadata", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<MobileControlPartnerMetadata> PartnerMetadata { get; set; }
|
||||
}
|
||||
|
||||
public class MobileControlPartnerMetadata
|
||||
{
|
||||
[JsonProperty("role")]
|
||||
public string Role { get; set; }
|
||||
|
||||
[JsonProperty("description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[JsonProperty("logoPath")]
|
||||
public string LogoPath { get; set; }
|
||||
}
|
||||
|
||||
public class McMode
|
||||
{
|
||||
[JsonProperty("listPageText")]
|
||||
public string ListPageText { get; set; }
|
||||
[JsonProperty("loginHelpText")]
|
||||
public string LoginHelpText { get; set; }
|
||||
|
||||
[JsonProperty("passcodePageText")]
|
||||
public string PasscodePageText { get; set; }
|
||||
}
|
||||
|
||||
public enum MCIconSet
|
||||
{
|
||||
GOOGLE,
|
||||
HABANERO,
|
||||
NEO
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class MobileControlDeviceFactory : EssentialsDeviceFactory<MobileControlSystemController>
|
||||
{
|
||||
public MobileControlDeviceFactory()
|
||||
{
|
||||
TypeNames = new List<string> { "appserver", "mobilecontrol", "webserver" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
try
|
||||
{
|
||||
var props = dc.Properties.ToObject<MobileControlConfig>();
|
||||
return new MobileControlSystemController(dc.Key, dc.Name, props);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(e, "Error building Mobile Control System Controller");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to overlay additional config data from mobile control on
|
||||
/// </summary>
|
||||
public class MobileControlEssentialsConfig : EssentialsConfig
|
||||
{
|
||||
[JsonProperty("runtimeInfo")]
|
||||
public MobileControlRuntimeInfo RuntimeInfo { get; set; }
|
||||
|
||||
public MobileControlEssentialsConfig(EssentialsConfig config)
|
||||
: base()
|
||||
{
|
||||
// TODO: Consider using Reflection to iterate properties
|
||||
this.Devices = config.Devices;
|
||||
this.Info = config.Info;
|
||||
this.JoinMaps = config.JoinMaps;
|
||||
this.Rooms = config.Rooms;
|
||||
this.SourceLists = config.SourceLists;
|
||||
this.DestinationLists = config.DestinationLists;
|
||||
this.SystemUrl = config.SystemUrl;
|
||||
this.TemplateUrl = config.TemplateUrl;
|
||||
this.TieLines = config.TieLines;
|
||||
|
||||
if (this.Info == null)
|
||||
this.Info = new InfoConfig();
|
||||
|
||||
RuntimeInfo = new MobileControlRuntimeInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to add any additional runtime information from mobile control to be send to the API
|
||||
/// </summary>
|
||||
public class MobileControlRuntimeInfo
|
||||
{
|
||||
[JsonProperty("pluginVersion")]
|
||||
public string PluginVersion { get; set; }
|
||||
|
||||
[JsonProperty("essentialsVersion")]
|
||||
public string EssentialsVersion { get; set; }
|
||||
|
||||
[JsonProperty("pepperDashCoreVersion")]
|
||||
public string PepperDashCoreVersion { get; set; }
|
||||
|
||||
[JsonProperty("essentialsPlugins")]
|
||||
public List<LoadedAssembly> EssentialsPlugins { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class MobileControlFactory
|
||||
{
|
||||
public MobileControlFactory()
|
||||
{
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
|
||||
PluginLoader.SetEssentialsAssembly(assembly.GetName().Name, assembly);
|
||||
|
||||
var types = assembly.GetTypes().Where(t => typeof(IDeviceFactory).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
|
||||
|
||||
if (types == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
var factory = (IDeviceFactory)Activator.CreateInstance(type);
|
||||
|
||||
factory.LoadTypeFactories();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Unable to load type '{type}' DeviceFactory: {factory}", null, type.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic device connection through to and EISC for SIMPL01
|
||||
/// </summary>
|
||||
public class MobileControlSimplDeviceBridge : Device, IChannel, INumericKeypad
|
||||
{
|
||||
/// <summary>
|
||||
/// EISC used to talk to Simpl
|
||||
/// </summary>
|
||||
private readonly ThreeSeriesTcpIpEthernetIntersystemCommunications _eisc;
|
||||
|
||||
public MobileControlSimplDeviceBridge(string key, string name,
|
||||
ThreeSeriesTcpIpEthernetIntersystemCommunications eisc)
|
||||
: base(key, name)
|
||||
{
|
||||
_eisc = eisc;
|
||||
}
|
||||
|
||||
#region IChannel Members
|
||||
|
||||
public void ChannelUp(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void ChannelDown(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void LastChannel(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Guide(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Info(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Exit(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region INumericKeypad Members
|
||||
|
||||
public void Digit0(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit1(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit2(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit3(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit4(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit5(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit6(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit7(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit8(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit9(bool pressRelease)
|
||||
{
|
||||
_eisc.SetBool(1111, pressRelease);
|
||||
}
|
||||
|
||||
public bool HasKeypadAccessoryButton1
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public string KeypadAccessoryButton1Label
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public void KeypadAccessoryButton1(bool pressRelease)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool HasKeypadAccessoryButton2
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public string KeypadAccessoryButton2Label
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public void KeypadAccessoryButton2(bool pressRelease)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,69 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<RootNamespace>PepperDash.Essentials</RootNamespace>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<Deterministic>false</Deterministic>
|
||||
<AssemblyTitle>epi-essentials-mobile-control</AssemblyTitle>
|
||||
<AssemblyName>epi-essentials-mobile-control</AssemblyName>
|
||||
<Company>PepperDash Technologies</Company>
|
||||
<Product>epi-essentials-mobile-control</Product>
|
||||
<Description>This software is a plugin designed to work as a part of PepperDash Essentials for Crestron control processors. This plugin allows for connection to a PepperDash Mobile Control server.</Description>
|
||||
<Copyright>Copyright 2020</Copyright>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<InformationalVersion>$(Version)</InformationalVersion>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<Authors>PepperDash Technologies</Authors>
|
||||
<PackageId>PepperDash.Essentials.MobileControl</PackageId>
|
||||
<PackageTags>crestron 4series</PackageTags>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DefineConstants>TRACE;DEBUG;SERIES4</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DefineConstants>TRACE;SERIES4</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="bin\**" />
|
||||
<EmbeddedResource Remove="bin\**" />
|
||||
<None Remove="bin\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="MobileControlSimplDeviceBridge.cs" />
|
||||
<Compile Remove="RoomBridges\MobileControlSIMPLRoomBridge.cs" />
|
||||
<Compile Remove="RoomBridges\SourceDeviceMapDictionary.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" />
|
||||
<PackageReference Include="PepperDashCore" Version="2.0.1" />
|
||||
<PackageReference Include="WebSocketSharp-netstandard" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="C:\Users\awelker\source\Essentials\Essentials\src\PepperDash.Essentials.MobileControl\bin\Debug\net472\PepperDash.Essentials.MobileControl.4.0.0-local.net472.cplz" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="C:\Users\awelker\source\Essentials\Essentials\src\PepperDash.Essentials.MobileControl\bin\Debug\net472\PepperDash.Essentials.MobileControl.4.0.0-local.net472.cplz" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PepperDash.Essentials.Core\PepperDash.Essentials.Core.csproj">
|
||||
<Private>false</Private>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PepperDash.Essentials.Devices.Common\PepperDash.Essentials.Devices.Common.csproj">
|
||||
<Private>false</Private>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PepperDash.Essentials.MobileControl.Messengers\PepperDash.Essentials.MobileControl.Messengers.csproj">
|
||||
<Private>false</Private>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,131 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.RoomBridges
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class MobileControlBridgeBase : MessengerBase, IMobileControlRoomMessenger
|
||||
{
|
||||
public event EventHandler<EventArgs> UserCodeChanged;
|
||||
|
||||
public event EventHandler<EventArgs> UserPromptedForCode;
|
||||
|
||||
public event EventHandler<EventArgs> ClientJoined;
|
||||
|
||||
public event EventHandler<EventArgs> AppUrlChanged;
|
||||
|
||||
public IMobileControl Parent { get; private set; }
|
||||
|
||||
public string AppUrl { get; private set; }
|
||||
public string UserCode { get; private set; }
|
||||
|
||||
public string QrCodeUrl { get; protected set; }
|
||||
|
||||
public string QrCodeChecksum { get; protected set; }
|
||||
|
||||
public string McServerUrl { get; private set; }
|
||||
|
||||
public abstract string RoomName { get; }
|
||||
|
||||
public abstract string RoomKey { get; }
|
||||
|
||||
protected MobileControlBridgeBase(string key, string messagePath)
|
||||
: base(key, messagePath)
|
||||
{
|
||||
}
|
||||
|
||||
protected MobileControlBridgeBase(string key, string messagePath, IKeyName device)
|
||||
: base(key, messagePath, device)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the parent. Does nothing else. Override to add functionality such
|
||||
/// as adding actions to parent
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
public virtual void AddParent(IMobileControl parent)
|
||||
{
|
||||
Parent = parent;
|
||||
|
||||
McServerUrl = Parent.ClientAppUrl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the UserCode on the bridge object. Called from controller. A changed code will
|
||||
/// fire method UserCodeChange. Override that to handle changes
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
public void SetUserCode(string code)
|
||||
{
|
||||
var changed = UserCode != code;
|
||||
UserCode = code;
|
||||
if (changed)
|
||||
{
|
||||
UserCodeChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the UserCode on the bridge object. Called from controller. A changed code will
|
||||
/// fire method UserCodeChange. Override that to handle changes
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="qrChecksum">Checksum of the QR code. Used for Cisco codec branding command</param>
|
||||
public void SetUserCode(string code, string qrChecksum)
|
||||
{
|
||||
QrCodeChecksum = qrChecksum;
|
||||
|
||||
SetUserCode(code);
|
||||
}
|
||||
|
||||
public virtual void UpdateAppUrl(string url)
|
||||
{
|
||||
AppUrl = url;
|
||||
|
||||
var handler = AppUrlChanged;
|
||||
|
||||
if (handler == null) return;
|
||||
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Empty method in base class. Override this to add functionality
|
||||
/// when code changes
|
||||
/// </summary>
|
||||
protected virtual void UserCodeChange()
|
||||
{
|
||||
this.LogDebug("Server user code changed: {userCode}", UserCode);
|
||||
|
||||
var qrUrl = string.Format($"{Parent.Host}/api/rooms/{Parent.SystemUuid}/{RoomKey}/qr?x={new Random().Next()}");
|
||||
QrCodeUrl = qrUrl;
|
||||
|
||||
this.LogDebug("Server user code changed: {userCode} - {qrCodeUrl}", UserCode, qrUrl);
|
||||
|
||||
OnUserCodeChanged();
|
||||
}
|
||||
|
||||
protected void OnUserCodeChanged()
|
||||
{
|
||||
UserCodeChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
|
||||
protected void OnUserPromptedForCode()
|
||||
{
|
||||
UserPromptedForCode?.Invoke(this, new EventArgs());
|
||||
}
|
||||
|
||||
protected void OnClientJoined()
|
||||
{
|
||||
ClientJoined?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,967 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.CrestronIO;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.Lighting;
|
||||
using PepperDash.Essentials.Core.Shades;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Room;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.WebSocketServer;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using IShades = PepperDash.Essentials.Core.Shades.IShades;
|
||||
using ShadeBase = PepperDash.Essentials.Devices.Common.Shades.ShadeBase;
|
||||
|
||||
namespace PepperDash.Essentials.RoomBridges
|
||||
{
|
||||
public class MobileControlEssentialsRoomBridge : MobileControlBridgeBase
|
||||
{
|
||||
private List<JoinToken> _touchPanelTokens = new List<JoinToken>();
|
||||
public IEssentialsRoom Room { get; private set; }
|
||||
|
||||
public string DefaultRoomKey { get; private set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override string RoomName
|
||||
{
|
||||
get { return Room.Name; }
|
||||
}
|
||||
|
||||
public override string RoomKey
|
||||
{
|
||||
get { return Room.Key; }
|
||||
}
|
||||
|
||||
public MobileControlEssentialsRoomBridge(IEssentialsRoom room) :
|
||||
this($"mobileControlBridge-{room.Key}", room.Key, room)
|
||||
{
|
||||
Room = room;
|
||||
}
|
||||
|
||||
public MobileControlEssentialsRoomBridge(string key, string roomKey, IEssentialsRoom room) : base(key, $"/room/{room.Key}", room as Device)
|
||||
{
|
||||
DefaultRoomKey = roomKey;
|
||||
|
||||
AddPreActivationAction(GetRoom);
|
||||
}
|
||||
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
// we add actions to the messaging system with a path, and a related action. Custom action
|
||||
// content objects can be handled in the controller's LineReceived method - and perhaps other
|
||||
// sub-controller parsing could be attached to these classes, so that the systemController
|
||||
// doesn't need to know about everything.
|
||||
|
||||
this.LogInformation("Registering Actions with AppServer");
|
||||
|
||||
AddAction("/promptForCode", (id, content) => OnUserPromptedForCode());
|
||||
AddAction("/clientJoined", (id, content) => OnClientJoined());
|
||||
|
||||
AddAction("/touchPanels", (id, content) => OnTouchPanelsUpdated(content));
|
||||
|
||||
AddAction($"/userApp", (id, content) => OnUserAppUpdated(content));
|
||||
|
||||
AddAction("/userCode", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<UserCodeChangedContent>();
|
||||
|
||||
SetUserCode(msg.UserCode, msg.QrChecksum ?? string.Empty);
|
||||
});
|
||||
|
||||
|
||||
// Source Changes and room off
|
||||
AddAction("/status", (id, content) =>
|
||||
{
|
||||
SendFullStatusForClientId(id, Room);
|
||||
});
|
||||
|
||||
if (Room is IRunRouteAction routeRoom)
|
||||
AddAction("/source", (id, content) =>
|
||||
{
|
||||
|
||||
var msg = content.ToObject<SourceSelectMessageContent>();
|
||||
|
||||
this.LogVerbose("Received request to route to source: {sourceListKey} on list: {sourceList}", msg.SourceListItemKey, msg.SourceListKey);
|
||||
|
||||
routeRoom.RunRouteAction(msg.SourceListItemKey, msg.SourceListKey);
|
||||
});
|
||||
|
||||
if (Room is IRunDirectRouteAction directRouteRoom)
|
||||
{
|
||||
AddAction("/directRoute", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<DirectRoute>();
|
||||
|
||||
|
||||
this.LogVerbose("Running direct route from {sourceKey} to {destinationKey} with signal type {signalType}", msg.SourceKey, msg.DestinationKey, msg.SignalType);
|
||||
|
||||
directRouteRoom.RunDirectRoute(msg.SourceKey, msg.DestinationKey, msg.SignalType);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (Room is IRunDefaultPresentRoute defaultRoom)
|
||||
AddAction("/defaultsource", (id, content) => defaultRoom.RunDefaultPresentRoute());
|
||||
|
||||
if (Room is IHasCurrentVolumeControls volumeRoom)
|
||||
{
|
||||
volumeRoom.CurrentVolumeDeviceChange += Room_CurrentVolumeDeviceChange;
|
||||
|
||||
if (volumeRoom.CurrentVolumeControls == null) return;
|
||||
|
||||
AddAction("/volumes/master/level", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<ushort>>();
|
||||
|
||||
|
||||
if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback basicVolumeWithFeedback)
|
||||
basicVolumeWithFeedback.SetVolume(msg.Value);
|
||||
});
|
||||
|
||||
AddAction("/volumes/master/muteToggle", (id, content) => volumeRoom.CurrentVolumeControls.MuteToggle());
|
||||
|
||||
AddAction("/volumes/master/muteOn", (id, content) =>
|
||||
{
|
||||
if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback basicVolumeWithFeedback)
|
||||
basicVolumeWithFeedback.MuteOn();
|
||||
});
|
||||
|
||||
AddAction("/volumes/master/muteOff", (id, content) =>
|
||||
{
|
||||
if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback basicVolumeWithFeedback)
|
||||
basicVolumeWithFeedback.MuteOff();
|
||||
});
|
||||
|
||||
AddAction("/volumes/master/volumeUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) =>
|
||||
{
|
||||
if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback basicVolumeWithFeedback)
|
||||
{
|
||||
basicVolumeWithFeedback.VolumeUp(b);
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
AddAction("/volumes/master/volumeDown", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) =>
|
||||
{
|
||||
if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback basicVolumeWithFeedback)
|
||||
{
|
||||
basicVolumeWithFeedback.VolumeDown(b);
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
|
||||
// Registers for initial volume events, if possible
|
||||
if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback currentVolumeDevice)
|
||||
{
|
||||
this.LogVerbose("Registering for volume feedback events");
|
||||
|
||||
currentVolumeDevice.MuteFeedback.OutputChange += MuteFeedback_OutputChange;
|
||||
currentVolumeDevice.VolumeLevelFeedback.OutputChange += VolumeLevelFeedback_OutputChange;
|
||||
}
|
||||
}
|
||||
|
||||
if (Room is IHasCurrentSourceInfoChange sscRoom)
|
||||
sscRoom.CurrentSourceChange += Room_CurrentSingleSourceChange;
|
||||
|
||||
if (Room is IEssentialsHuddleVtc1Room vtcRoom)
|
||||
{
|
||||
if (vtcRoom.ScheduleSource != null)
|
||||
{
|
||||
var key = vtcRoom.Key + "-" + Key;
|
||||
|
||||
if (!AppServerController.CheckForDeviceMessenger(key))
|
||||
{
|
||||
var scheduleMessenger = new IHasScheduleAwarenessMessenger(key, vtcRoom.ScheduleSource,
|
||||
$"/room/{vtcRoom.Key}");
|
||||
AppServerController.AddDeviceMessenger(scheduleMessenger);
|
||||
}
|
||||
}
|
||||
|
||||
vtcRoom.InCallFeedback.OutputChange += InCallFeedback_OutputChange;
|
||||
}
|
||||
|
||||
if (Room is IPrivacy privacyRoom)
|
||||
{
|
||||
AddAction("/volumes/master/privacyMuteToggle", (id, content) => privacyRoom.PrivacyModeToggle());
|
||||
|
||||
privacyRoom.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
|
||||
}
|
||||
|
||||
|
||||
if (Room is IRunDefaultCallRoute defCallRm)
|
||||
{
|
||||
AddAction("/activityVideo", (id, content) => defCallRm.RunDefaultCallRoute());
|
||||
}
|
||||
|
||||
Room.OnFeedback.OutputChange += OnFeedback_OutputChange;
|
||||
Room.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
|
||||
Room.IsWarmingUpFeedback.OutputChange += IsWarmingUpFeedback_OutputChange;
|
||||
|
||||
AddTechRoomActions();
|
||||
}
|
||||
|
||||
private void OnTouchPanelsUpdated(JToken content)
|
||||
{
|
||||
var message = content.ToObject<ApiTouchPanelToken>();
|
||||
|
||||
_touchPanelTokens = message.TouchPanels;
|
||||
|
||||
UpdateTouchPanelAppUrls(message.UserAppUrl);
|
||||
}
|
||||
|
||||
private void UpdateTouchPanelAppUrls(string userAppUrl)
|
||||
{
|
||||
foreach (var tp in _touchPanelTokens)
|
||||
{
|
||||
var dev = DeviceManager.AllDevices.OfType<IMobileControlTouchpanelController>().FirstOrDefault((tpc) => tpc.Key.Equals(tp.TouchpanelKey, StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
if (dev == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//UpdateAppUrl($"{userAppUrl}?token={tp.Token}");
|
||||
|
||||
dev.SetAppUrl($"{userAppUrl}?token={tp.Token}");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUserAppUpdated(JToken content)
|
||||
{
|
||||
var message = content.ToObject<ApiTouchPanelToken>();
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Updating User App URL to {userAppUrl}. Full Message: {@message}", this, message.UserAppUrl, content);
|
||||
|
||||
UpdateTouchPanelAppUrls(message.UserAppUrl);
|
||||
}
|
||||
|
||||
private void InCallFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
var state = new RoomStateMessage
|
||||
{
|
||||
IsInCall = e.BoolValue
|
||||
};
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
private void GetRoom()
|
||||
{
|
||||
if (Room != null)
|
||||
{
|
||||
this.LogInformation("Room with key {key} already linked.", DefaultRoomKey);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!(DeviceManager.GetDeviceForKey(DefaultRoomKey) is IEssentialsRoom tempRoom))
|
||||
{
|
||||
this.LogInformation("Room with key {key} not found or is not an Essentials Room", DefaultRoomKey);
|
||||
return;
|
||||
}
|
||||
|
||||
Room = tempRoom;
|
||||
}
|
||||
|
||||
protected override void UserCodeChange()
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Server user code changed: {userCode}", this, UserCode);
|
||||
|
||||
var qrUrl = string.Format("{0}/rooms/{1}/{3}/qr?x={2}", Parent?.Host, Parent?.SystemUuid, new Random().Next(), DefaultRoomKey);
|
||||
|
||||
QrCodeUrl = qrUrl;
|
||||
|
||||
this.LogDebug("Server user code changed: {userCode} - {qrUrl}", UserCode, qrUrl);
|
||||
|
||||
OnUserCodeChanged();
|
||||
}
|
||||
|
||||
/* /// <summary>
|
||||
/// Override of base: calls base to add parent and then registers actions and events.
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
public override void AddParent(MobileControlSystemController parent)
|
||||
{
|
||||
base.AddParent(parent);
|
||||
|
||||
}*/
|
||||
|
||||
private void AddTechRoomActions()
|
||||
{
|
||||
if (!(Room is IEssentialsTechRoom techRoom))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AddAction("/roomPowerOn", (id, content) => techRoom.RoomPowerOn());
|
||||
AddAction("/roomPowerOff", (id, content) => techRoom.RoomPowerOff());
|
||||
}
|
||||
|
||||
private void PrivacyModeIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
var state = new RoomStateMessage();
|
||||
|
||||
var volumes = new Dictionary<string, Volume>
|
||||
{
|
||||
{ "master", new Volume("master")
|
||||
{
|
||||
PrivacyMuted = e.BoolValue
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
state.Volumes = volumes;
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void IsSharingFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
// sharing source
|
||||
string shareText;
|
||||
bool isSharing;
|
||||
|
||||
if (Room is IHasCurrentSourceInfoChange srcInfoRoom && Room is IHasVideoCodec vcRoom && vcRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && srcInfoRoom.CurrentSourceInfo != null)
|
||||
{
|
||||
shareText = srcInfoRoom.CurrentSourceInfo.PreferredName;
|
||||
isSharing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
shareText = "None";
|
||||
isSharing = false;
|
||||
}
|
||||
|
||||
var state = new RoomStateMessage
|
||||
{
|
||||
Share = new ShareState
|
||||
{
|
||||
CurrentShareText = shareText,
|
||||
IsSharing = isSharing
|
||||
}
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void IsWarmingUpFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
var state = new
|
||||
{
|
||||
isWarmingUp = e.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(JToken.FromObject(state));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void IsCoolingDownFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
var state = new
|
||||
{
|
||||
isCoolingDown = e.BoolValue
|
||||
};
|
||||
PostStatusMessage(JToken.FromObject(state));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void OnFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
var state = new
|
||||
{
|
||||
isOn = e.BoolValue
|
||||
};
|
||||
PostStatusMessage(JToken.FromObject(state));
|
||||
}
|
||||
|
||||
private void Room_CurrentVolumeDeviceChange(object sender, VolumeDeviceChangeEventArgs e)
|
||||
{
|
||||
if (e.OldDev is IBasicVolumeWithFeedback)
|
||||
{
|
||||
var oldDev = e.OldDev as IBasicVolumeWithFeedback;
|
||||
oldDev.MuteFeedback.OutputChange -= MuteFeedback_OutputChange;
|
||||
oldDev.VolumeLevelFeedback.OutputChange -= VolumeLevelFeedback_OutputChange;
|
||||
}
|
||||
|
||||
if (e.NewDev is IBasicVolumeWithFeedback)
|
||||
{
|
||||
var newDev = e.NewDev as IBasicVolumeWithFeedback;
|
||||
newDev.MuteFeedback.OutputChange += MuteFeedback_OutputChange;
|
||||
newDev.VolumeLevelFeedback.OutputChange += VolumeLevelFeedback_OutputChange;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for mute changes
|
||||
/// </summary>
|
||||
private void MuteFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
var state = new RoomStateMessage();
|
||||
|
||||
var volumes = new Dictionary<string, Volume>
|
||||
{
|
||||
{ "master", new Volume("master", e.BoolValue) }
|
||||
};
|
||||
|
||||
state.Volumes = volumes;
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles Volume changes on room
|
||||
/// </summary>
|
||||
private void VolumeLevelFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
|
||||
var state = new
|
||||
{
|
||||
volumes = new Dictionary<string, Volume>
|
||||
{
|
||||
{ "master", new Volume("master", e.IntValue) }
|
||||
}
|
||||
};
|
||||
PostStatusMessage(JToken.FromObject(state));
|
||||
}
|
||||
|
||||
|
||||
private void Room_CurrentSingleSourceChange(SourceListItem info, ChangeType type)
|
||||
{
|
||||
/* Example message
|
||||
* {
|
||||
"type":"/room/status",
|
||||
"content": {
|
||||
"selectedSourceKey": "off",
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the full status of the room to the server
|
||||
/// </summary>
|
||||
/// <param name="room"></param>
|
||||
private void SendFullStatusForClientId(string id, IEssentialsRoom room)
|
||||
{
|
||||
//Parent.SendMessageObject(GetFullStatus(room));
|
||||
var message = GetFullStatusForClientId(room);
|
||||
|
||||
if (message == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
PostStatusMessage(message, id);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets full room status
|
||||
/// </summary>
|
||||
/// <param name="room">The room to get status of</param>
|
||||
/// <returns>The status response message</returns>
|
||||
private RoomStateMessage GetFullStatusForClientId(IEssentialsRoom room)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.LogVerbose("GetFullStatus");
|
||||
|
||||
var sourceKey = room is IHasCurrentSourceInfoChange ? (room as IHasCurrentSourceInfoChange).CurrentSourceInfoKey : null;
|
||||
|
||||
var volumes = new Dictionary<string, Volume>();
|
||||
if (room is IHasCurrentVolumeControls rmVc)
|
||||
{
|
||||
if (rmVc.CurrentVolumeControls is IBasicVolumeWithFeedback vc)
|
||||
{
|
||||
var volume = new Volume("master", vc.VolumeLevelFeedback.UShortValue, vc.MuteFeedback.BoolValue, "Volume", true, "");
|
||||
if (room is IPrivacy privacyRoom)
|
||||
{
|
||||
volume.HasPrivacyMute = true;
|
||||
volume.PrivacyMuted = privacyRoom.PrivacyModeIsOnFeedback.BoolValue;
|
||||
}
|
||||
|
||||
volumes.Add("master", volume);
|
||||
}
|
||||
}
|
||||
|
||||
var state = new RoomStateMessage
|
||||
{
|
||||
Configuration = GetRoomConfiguration(room),
|
||||
ActivityMode = 1,
|
||||
IsOn = room.OnFeedback.BoolValue,
|
||||
SelectedSourceKey = sourceKey,
|
||||
Volumes = volumes,
|
||||
IsWarmingUp = room.IsWarmingUpFeedback.BoolValue,
|
||||
IsCoolingDown = room.IsCoolingDownFeedback.BoolValue
|
||||
};
|
||||
|
||||
if (room is IEssentialsHuddleVtc1Room vtcRoom)
|
||||
{
|
||||
state.IsInCall = vtcRoom.InCallFeedback.BoolValue;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Error getting full status", this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the configuration of the room and the details about the devices associated with the room
|
||||
/// <param name="room"></param>
|
||||
/// <returns></returns>
|
||||
private RoomConfiguration GetRoomConfiguration(IEssentialsRoom room)
|
||||
{
|
||||
try
|
||||
{
|
||||
var configuration = new RoomConfiguration
|
||||
{
|
||||
//ShutdownPromptSeconds = room.ShutdownPromptSeconds,
|
||||
TouchpanelKeys = DeviceManager.AllDevices.
|
||||
OfType<IMobileControlTouchpanelController>()
|
||||
.Where((tp) => tp.DefaultRoomKey.Equals(room.Key, StringComparison.InvariantCultureIgnoreCase))
|
||||
.Select(tp => tp.Key).ToList()
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var zrcTp = DeviceManager.AllDevices.OfType<IMobileControlTouchpanelController>().SingleOrDefault((tp) => tp.ZoomRoomController);
|
||||
|
||||
configuration.ZoomRoomControllerKey = zrcTp?.Key;
|
||||
}
|
||||
catch
|
||||
{
|
||||
configuration.ZoomRoomControllerKey = room.Key;
|
||||
}
|
||||
|
||||
if (room is IHasCiscoNavigatorTouchpanel ciscoNavRoom)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, $"Setting CiscoNavigatorKey to: {ciscoNavRoom.CiscoNavigatorTouchpanelKey}", this);
|
||||
configuration.CiscoNavigatorKey = ciscoNavRoom.CiscoNavigatorTouchpanelKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// find the room combiner for this room by checking if the room is in the list of rooms for the room combiner
|
||||
var roomCombiner = DeviceManager.AllDevices.OfType<IEssentialsRoomCombiner>().FirstOrDefault();
|
||||
|
||||
configuration.RoomCombinerKey = roomCombiner?.Key;
|
||||
|
||||
|
||||
if (room is IEssentialsRoomPropertiesConfig propertiesConfig)
|
||||
{
|
||||
configuration.HelpMessage = propertiesConfig.PropertiesConfig.HelpMessageForDisplay;
|
||||
}
|
||||
|
||||
if (room is IEssentialsHuddleSpaceRoom huddleRoom && !string.IsNullOrEmpty(huddleRoom.PropertiesConfig.HelpMessageForDisplay))
|
||||
{
|
||||
this.LogVerbose("Getting huddle room config");
|
||||
configuration.HelpMessage = huddleRoom.PropertiesConfig.HelpMessageForDisplay;
|
||||
configuration.UiBehavior = huddleRoom.PropertiesConfig.UiBehavior;
|
||||
configuration.DefaultPresentationSourceKey = huddleRoom.PropertiesConfig.DefaultSourceItem;
|
||||
|
||||
}
|
||||
|
||||
if (room is IEssentialsHuddleVtc1Room vtc1Room && !string.IsNullOrEmpty(vtc1Room.PropertiesConfig.HelpMessageForDisplay))
|
||||
{
|
||||
this.LogVerbose("Getting vtc room config");
|
||||
configuration.HelpMessage = vtc1Room.PropertiesConfig.HelpMessageForDisplay;
|
||||
configuration.UiBehavior = vtc1Room.PropertiesConfig.UiBehavior;
|
||||
configuration.DefaultPresentationSourceKey = vtc1Room.PropertiesConfig.DefaultSourceItem;
|
||||
}
|
||||
|
||||
if (room is IEssentialsTechRoom techRoom && !string.IsNullOrEmpty(techRoom.PropertiesConfig.HelpMessage))
|
||||
{
|
||||
this.LogVerbose("Getting tech room config");
|
||||
configuration.HelpMessage = techRoom.PropertiesConfig.HelpMessage;
|
||||
}
|
||||
|
||||
if (room is IHasVideoCodec vcRoom)
|
||||
{
|
||||
if (vcRoom.VideoCodec != null)
|
||||
{
|
||||
this.LogVerbose("Getting codec config");
|
||||
var type = vcRoom.VideoCodec.GetType();
|
||||
|
||||
configuration.HasVideoConferencing = true;
|
||||
configuration.VideoCodecKey = vcRoom.VideoCodec.Key;
|
||||
configuration.VideoCodecIsZoomRoom = type.Name.Equals("ZoomRoom", StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
if (room is IHasAudioCodec acRoom)
|
||||
{
|
||||
if (acRoom.AudioCodec != null)
|
||||
{
|
||||
this.LogVerbose("Getting audio codec config");
|
||||
configuration.HasAudioConferencing = true;
|
||||
configuration.AudioCodecKey = acRoom.AudioCodec.Key;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (room is IHasMatrixRouting matrixRoutingRoom)
|
||||
{
|
||||
this.LogVerbose("Getting matrix routing config");
|
||||
configuration.MatrixRoutingKey = matrixRoutingRoom.MatrixRoutingDeviceKey;
|
||||
configuration.EndpointKeys = matrixRoutingRoom.EndpointKeys;
|
||||
}
|
||||
|
||||
if (room is IEnvironmentalControls envRoom)
|
||||
{
|
||||
this.LogVerbose("Getting environmental controls config. RoomHasEnvironmentalControls: {hasEnvironmentalControls}", envRoom.HasEnvironmentalControlDevices);
|
||||
configuration.HasEnvironmentalControls = envRoom.HasEnvironmentalControlDevices;
|
||||
|
||||
if (envRoom.HasEnvironmentalControlDevices)
|
||||
{
|
||||
this.LogVerbose("Room Has {count} Environmental Control Devices.", envRoom.EnvironmentalControlDevices.Count);
|
||||
|
||||
foreach (var dev in envRoom.EnvironmentalControlDevices)
|
||||
{
|
||||
this.LogVerbose("Adding environmental device: {key}", dev.Key);
|
||||
|
||||
eEnvironmentalDeviceTypes type = eEnvironmentalDeviceTypes.None;
|
||||
|
||||
if (dev is ILightingScenes)
|
||||
{
|
||||
type = eEnvironmentalDeviceTypes.Lighting;
|
||||
}
|
||||
else if (dev is ShadeBase || dev is IShadesOpenCloseStop || dev is IShadesOpenClosePreset)
|
||||
{
|
||||
type = eEnvironmentalDeviceTypes.Shade;
|
||||
}
|
||||
else if (dev is IShades)
|
||||
{
|
||||
type = eEnvironmentalDeviceTypes.ShadeController;
|
||||
}
|
||||
else if (dev is ISwitchedOutput)
|
||||
{
|
||||
type = eEnvironmentalDeviceTypes.Relay;
|
||||
}
|
||||
|
||||
this.LogVerbose("Environmental Device Type: {type}", type);
|
||||
|
||||
var envDevice = new EnvironmentalDeviceConfiguration(dev.Key, type);
|
||||
|
||||
configuration.EnvironmentalDevices.Add(envDevice);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.LogVerbose("Room Has No Environmental Control Devices");
|
||||
}
|
||||
}
|
||||
|
||||
if (room is IHasDefaultDisplay defDisplayRoom)
|
||||
{
|
||||
this.LogVerbose("Getting default display config");
|
||||
configuration.DefaultDisplayKey = defDisplayRoom.DefaultDisplay.Key;
|
||||
configuration.Destinations.Add(eSourceListItemDestinationTypes.defaultDisplay, defDisplayRoom.DefaultDisplay.Key);
|
||||
}
|
||||
|
||||
if (room is IHasMultipleDisplays multiDisplayRoom)
|
||||
{
|
||||
this.LogVerbose("Getting multiple display config");
|
||||
|
||||
if (multiDisplayRoom.Displays == null)
|
||||
{
|
||||
this.LogVerbose("Displays collection is null");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.LogVerbose("Displays collection exists");
|
||||
|
||||
configuration.Destinations = multiDisplayRoom.Displays.ToDictionary(kv => kv.Key, kv => kv.Value.Key);
|
||||
}
|
||||
}
|
||||
|
||||
if (room is IHasAccessoryDevices accRoom)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Getting accessory devices config", this);
|
||||
|
||||
if (accRoom.AccessoryDeviceKeys == null)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Accessory devices collection is null", this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Accessory devices collection exists", this);
|
||||
|
||||
configuration.AccessoryDeviceKeys = accRoom.AccessoryDeviceKeys;
|
||||
}
|
||||
}
|
||||
|
||||
var sourceList = ConfigReader.ConfigObject.GetSourceListForKey(room.SourceListKey);
|
||||
if (sourceList != null)
|
||||
{
|
||||
this.LogVerbose("Getting source list config");
|
||||
configuration.SourceList = sourceList;
|
||||
configuration.HasRoutingControls = true;
|
||||
|
||||
foreach (var source in sourceList)
|
||||
{
|
||||
if (source.Value.SourceDevice is Devices.Common.IRSetTopBoxBase)
|
||||
{
|
||||
configuration.HasSetTopBoxControls = true;
|
||||
continue;
|
||||
}
|
||||
else if (source.Value.SourceDevice is CameraBase)
|
||||
{
|
||||
configuration.HasCameraControls = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var destinationList = ConfigReader.ConfigObject.GetDestinationListForKey(room.DestinationListKey);
|
||||
|
||||
if (destinationList != null)
|
||||
{
|
||||
configuration.DestinationList = destinationList;
|
||||
}
|
||||
|
||||
var audioControlPointList = ConfigReader.ConfigObject.GetAudioControlPointListForKey(room.AudioControlPointListKey);
|
||||
|
||||
if (audioControlPointList != null)
|
||||
{
|
||||
configuration.AudioControlPointList = audioControlPointList;
|
||||
}
|
||||
|
||||
var cameraList = ConfigReader.ConfigObject.GetCameraListForKey(room.CameraListKey);
|
||||
|
||||
if (cameraList != null)
|
||||
{
|
||||
configuration.CameraList = cameraList;
|
||||
}
|
||||
|
||||
return configuration;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception getting room configuration");
|
||||
return new RoomConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class RoomStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("configuration", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public RoomConfiguration Configuration { get; set; }
|
||||
|
||||
[JsonProperty("activityMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? ActivityMode { get; set; }
|
||||
[JsonProperty("advancedSharingActive", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? AdvancedSharingActive { get; set; }
|
||||
[JsonProperty("isOn", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsOn { get; set; }
|
||||
[JsonProperty("isWarmingUp", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsWarmingUp { get; set; }
|
||||
[JsonProperty("isCoolingDown", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsCoolingDown { get; set; }
|
||||
[JsonProperty("selectedSourceKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string SelectedSourceKey { get; set; }
|
||||
[JsonProperty("share", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public ShareState Share { get; set; }
|
||||
|
||||
[JsonProperty("volumes", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Dictionary<string, Volume> Volumes { get; set; }
|
||||
|
||||
[JsonProperty("isInCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsInCall { get; set; }
|
||||
}
|
||||
|
||||
public class ShareState
|
||||
{
|
||||
[JsonProperty("currentShareText", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CurrentShareText { get; set; }
|
||||
[JsonProperty("enabled", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? Enabled { get; set; }
|
||||
[JsonProperty("isSharing", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsSharing { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the capabilities of the room and the associated device info
|
||||
/// </summary>
|
||||
public class RoomConfiguration
|
||||
{
|
||||
//[JsonProperty("shutdownPromptSeconds", NullValueHandling = NullValueHandling.Ignore)]
|
||||
//public int? ShutdownPromptSeconds { get; set; }
|
||||
|
||||
[JsonProperty("hasVideoConferencing", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasVideoConferencing { get; set; }
|
||||
[JsonProperty("videoCodecIsZoomRoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? VideoCodecIsZoomRoom { get; set; }
|
||||
[JsonProperty("hasAudioConferencing", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasAudioConferencing { get; set; }
|
||||
[JsonProperty("hasEnvironmentalControls", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasEnvironmentalControls { get; set; }
|
||||
[JsonProperty("hasCameraControls", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasCameraControls { get; set; }
|
||||
[JsonProperty("hasSetTopBoxControls", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasSetTopBoxControls { get; set; }
|
||||
[JsonProperty("hasRoutingControls", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasRoutingControls { get; set; }
|
||||
|
||||
[JsonProperty("touchpanelKeys", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<string> TouchpanelKeys { get; set; }
|
||||
|
||||
[JsonProperty("zoomRoomControllerKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string ZoomRoomControllerKey { get; set; }
|
||||
|
||||
[JsonProperty("ciscoNavigatorKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CiscoNavigatorKey { get; set; }
|
||||
|
||||
|
||||
[JsonProperty("videoCodecKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string VideoCodecKey { get; set; }
|
||||
[JsonProperty("audioCodecKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string AudioCodecKey { get; set; }
|
||||
[JsonProperty("matrixRoutingKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string MatrixRoutingKey { get; set; }
|
||||
[JsonProperty("endpointKeys", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<string> EndpointKeys { get; set; }
|
||||
|
||||
[JsonProperty("accessoryDeviceKeys", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<string> AccessoryDeviceKeys { get; set; }
|
||||
|
||||
[JsonProperty("defaultDisplayKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string DefaultDisplayKey { get; set; }
|
||||
[JsonProperty("destinations", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Dictionary<eSourceListItemDestinationTypes, string> Destinations { get; set; }
|
||||
[JsonProperty("environmentalDevices", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<EnvironmentalDeviceConfiguration> EnvironmentalDevices { get; set; }
|
||||
[JsonProperty("sourceList", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Dictionary<string, SourceListItem> SourceList { get; set; }
|
||||
|
||||
[JsonProperty("destinationList", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Dictionary<string, DestinationListItem> DestinationList { get; set; }
|
||||
|
||||
[JsonProperty("audioControlPointList", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public AudioControlPointListItem AudioControlPointList { get; set; }
|
||||
|
||||
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Dictionary<string, CameraListItem> CameraList { get; set; }
|
||||
|
||||
[JsonProperty("defaultPresentationSourceKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string DefaultPresentationSourceKey { get; set; }
|
||||
|
||||
|
||||
[JsonProperty("helpMessage", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string HelpMessage { get; set; }
|
||||
|
||||
[JsonProperty("techPassword", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string TechPassword { get; set; }
|
||||
|
||||
[JsonProperty("uiBehavior", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
|
||||
|
||||
[JsonProperty("supportsAdvancedSharing", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? SupportsAdvancedSharing { get; set; }
|
||||
[JsonProperty("userCanChangeShareMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? UserCanChangeShareMode { get; set; }
|
||||
|
||||
[JsonProperty("roomCombinerKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string RoomCombinerKey { get; set; }
|
||||
|
||||
public RoomConfiguration()
|
||||
{
|
||||
Destinations = new Dictionary<eSourceListItemDestinationTypes, string>();
|
||||
EnvironmentalDevices = new List<EnvironmentalDeviceConfiguration>();
|
||||
SourceList = new Dictionary<string, SourceListItem>();
|
||||
TouchpanelKeys = new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public class EnvironmentalDeviceConfiguration
|
||||
{
|
||||
[JsonProperty("deviceKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string DeviceKey { get; private set; }
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonProperty("deviceType", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public eEnvironmentalDeviceTypes DeviceType { get; private set; }
|
||||
|
||||
public EnvironmentalDeviceConfiguration(string key, eEnvironmentalDeviceTypes type)
|
||||
{
|
||||
DeviceKey = key;
|
||||
DeviceType = type;
|
||||
}
|
||||
}
|
||||
|
||||
public enum eEnvironmentalDeviceTypes
|
||||
{
|
||||
None,
|
||||
Lighting,
|
||||
Shade,
|
||||
ShadeController,
|
||||
Relay,
|
||||
}
|
||||
|
||||
public class ApiTouchPanelToken
|
||||
{
|
||||
[JsonProperty("touchPanels", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<JoinToken> TouchPanels { get; set; } = new List<JoinToken>();
|
||||
|
||||
[JsonProperty("userAppUrl", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string UserAppUrl { get; set; } = "";
|
||||
}
|
||||
|
||||
#if SERIES3
|
||||
public class SourceSelectMessageContent
|
||||
{
|
||||
public string SourceListItem { get; set; }
|
||||
public string SourceListKey { get; set; }
|
||||
}
|
||||
|
||||
public class DirectRoute
|
||||
{
|
||||
public string SourceKey { get; set; }
|
||||
public string DestinationKey { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
public delegate void PressAndHoldAction(bool b);
|
||||
#endif
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,96 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains all of the default joins that map to API funtions
|
||||
/// </summary>
|
||||
public class SourceDeviceMapDictionary : Dictionary<string, uint>
|
||||
{
|
||||
public SourceDeviceMapDictionary()
|
||||
{
|
||||
var dictionary = new Dictionary<string, uint>
|
||||
{
|
||||
{"preset01", 101},
|
||||
{"preset02", 102},
|
||||
{"preset03", 103},
|
||||
{"preset04", 104},
|
||||
{"preset05", 105},
|
||||
{"preset06", 106},
|
||||
{"preset07", 107},
|
||||
{"preset08", 108},
|
||||
{"preset09", 109},
|
||||
{"preset10", 110},
|
||||
{"preset11", 111},
|
||||
{"preset12", 112},
|
||||
{"preset13", 113},
|
||||
{"preset14", 114},
|
||||
{"preset15", 115},
|
||||
{"preset16", 116},
|
||||
{"preset17", 117},
|
||||
{"preset18", 118},
|
||||
{"preset19", 119},
|
||||
{"preset20", 120},
|
||||
{"preset21", 121},
|
||||
{"preset22", 122},
|
||||
{"preset23", 123},
|
||||
{"preset24", 124},
|
||||
{"num0", 130},
|
||||
{"num1", 131},
|
||||
{"num2", 132},
|
||||
{"num3", 133},
|
||||
{"num4", 134},
|
||||
{"num5", 135},
|
||||
{"num6", 136},
|
||||
{"num7", 137},
|
||||
{"num8", 138},
|
||||
{"num9", 139},
|
||||
{"numDash", 140},
|
||||
{"numEnter", 141},
|
||||
{"chanUp", 142},
|
||||
{"chanDown", 143},
|
||||
{"lastChan", 144},
|
||||
{"exit", 145},
|
||||
{"powerToggle", 146},
|
||||
{"red", 147},
|
||||
{"green", 148},
|
||||
{"yellow", 149},
|
||||
{"blue", 150},
|
||||
{"video", 151},
|
||||
{"previous", 152},
|
||||
{"next", 153},
|
||||
{"rewind", 154},
|
||||
{"ffwd", 155},
|
||||
{"closedCaption", 156},
|
||||
{"stop", 157},
|
||||
{"pause", 158},
|
||||
{"up", 159},
|
||||
{"down", 160},
|
||||
{"left", 161},
|
||||
{"right", 162},
|
||||
{"settings", 163},
|
||||
{"info", 164},
|
||||
{"return", 165},
|
||||
{"guide", 166},
|
||||
{"reboot", 167},
|
||||
{"dvrList", 168},
|
||||
{"replay", 169},
|
||||
{"play", 170},
|
||||
{"select", 171},
|
||||
{"record", 172},
|
||||
{"menu", 173},
|
||||
{"topMenu", 174},
|
||||
{"prevTrack", 175},
|
||||
{"nextTrack", 176},
|
||||
{"powerOn", 177},
|
||||
{"powerOff", 178},
|
||||
{"dot", 179}
|
||||
};
|
||||
|
||||
foreach (var item in dictionary)
|
||||
{
|
||||
Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.Services
|
||||
{
|
||||
|
||||
public class MobileControlApiService
|
||||
{
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public MobileControlApiService(string apiUrl)
|
||||
{
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
AllowAutoRedirect = false,
|
||||
ServerCertificateCustomValidationCallback = (req, cert, certChain, errors) => true
|
||||
};
|
||||
|
||||
_client = new HttpClient(handler);
|
||||
}
|
||||
|
||||
public async Task<AuthorizationResponse> SendAuthorizationRequest(string apiUrl, string grantCode, string systemUuid)
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, $"{apiUrl}/system/{systemUuid}/authorize?grantCode={grantCode}");
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Sending authorization request to {host}", null, request.RequestUri);
|
||||
|
||||
var response = await _client.SendAsync(request);
|
||||
|
||||
var authResponse = new AuthorizationResponse
|
||||
{
|
||||
Authorized = response.StatusCode == System.Net.HttpStatusCode.OK
|
||||
};
|
||||
|
||||
if (authResponse.Authorized)
|
||||
{
|
||||
return authResponse;
|
||||
}
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.Moved)
|
||||
{
|
||||
var location = response.Headers.Location;
|
||||
|
||||
authResponse.Reason = $"ERROR: Mobile Control API has moved. Please adjust configuration to \"{location}\"";
|
||||
|
||||
return authResponse;
|
||||
}
|
||||
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
switch (responseString)
|
||||
{
|
||||
case "codeNotFound":
|
||||
authResponse.Reason = $"Authorization failed. Code not found for system UUID {systemUuid}";
|
||||
break;
|
||||
case "uuidNotFound":
|
||||
authResponse.Reason = $"Authorization failed. System UUID {systemUuid} not found. Check Essentials configuration.";
|
||||
break;
|
||||
default:
|
||||
authResponse.Reason = $"Authorization failed. Response {response.StatusCode}: {responseString}";
|
||||
break;
|
||||
}
|
||||
|
||||
return authResponse;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Error authorizing with Mobile Control");
|
||||
return new AuthorizationResponse { Authorized = false, Reason = ex.Message };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
{
|
||||
public interface ITheme : IKeyed
|
||||
{
|
||||
string Theme { get; }
|
||||
|
||||
void UpdateTheme(string theme);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
{
|
||||
public interface ITswAppControl : IKeyed
|
||||
{
|
||||
BoolFeedback AppOpenFeedback { get; }
|
||||
|
||||
void HideOpenApp();
|
||||
|
||||
void CloseOpenApp();
|
||||
|
||||
void OpenApp();
|
||||
}
|
||||
|
||||
public interface ITswZoomControl : IKeyed
|
||||
{
|
||||
BoolFeedback ZoomIncomingCallFeedback { get; }
|
||||
|
||||
BoolFeedback ZoomInCallFeedback { get; }
|
||||
|
||||
void EndZoomCall();
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
{
|
||||
public class ITswAppControlMessenger : MessengerBase
|
||||
{
|
||||
private readonly ITswAppControl _appControl;
|
||||
|
||||
public ITswAppControlMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
_appControl = device as ITswAppControl;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
if (_appControl == null)
|
||||
{
|
||||
this.LogInformation("{deviceKey} does not implement ITswAppControl", _device.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
AddAction($"/fullStatus", (id, context) => SendFullStatus());
|
||||
|
||||
AddAction($"/openApp", (id, context) => _appControl.OpenApp());
|
||||
|
||||
AddAction($"/closeApp", (id, context) => _appControl.CloseOpenApp());
|
||||
|
||||
AddAction($"/hideApp", (id, context) => _appControl.HideOpenApp());
|
||||
|
||||
_appControl.AppOpenFeedback.OutputChange += (s, a) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
appOpen = a.BoolValue
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var message = new TswAppStateMessage
|
||||
{
|
||||
AppOpen = _appControl.AppOpenFeedback.BoolValue,
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public class TswAppStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("appOpen", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? AppOpen { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
{
|
||||
public class ITswZoomControlMessenger : MessengerBase
|
||||
{
|
||||
private readonly ITswZoomControl _zoomControl;
|
||||
|
||||
public ITswZoomControlMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
_zoomControl = device as ITswZoomControl;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
if (_zoomControl == null)
|
||||
{
|
||||
this.LogInformation("{deviceKey} does not implement ITswZoomControl", _device.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
AddAction($"/fullStatus", (id, context) => SendFullStatus());
|
||||
|
||||
|
||||
AddAction($"/endCall", (id, context) => _zoomControl.EndZoomCall());
|
||||
|
||||
_zoomControl.ZoomIncomingCallFeedback.OutputChange += (s, a) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
incomingCall = a.BoolValue,
|
||||
inCall = _zoomControl.ZoomInCallFeedback.BoolValue
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
_zoomControl.ZoomInCallFeedback.OutputChange += (s, a) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(
|
||||
new
|
||||
{
|
||||
inCall = a.BoolValue,
|
||||
incomingCall = _zoomControl.ZoomIncomingCallFeedback.BoolValue
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var message = new TswZoomStateMessage
|
||||
{
|
||||
InCall = _zoomControl?.ZoomInCallFeedback.BoolValue,
|
||||
IncomingCall = _zoomControl?.ZoomIncomingCallFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public class TswZoomStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("inCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? InCall { get; set; }
|
||||
|
||||
[JsonProperty("incomingCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IncomingCall { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,571 +0,0 @@
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.DeviceInfo;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
{
|
||||
//public interface IMobileControlTouchpanelController
|
||||
//{
|
||||
// StringFeedback AppUrlFeedback { get; }
|
||||
// string DefaultRoomKey { get; }
|
||||
// string DeviceKey { get; }
|
||||
//}
|
||||
|
||||
|
||||
public class MobileControlTouchpanelController : TouchpanelBase, IHasFeedback, ITswAppControl, ITswZoomControl, IDeviceInfoProvider, IMobileControlTouchpanelController, ITheme
|
||||
{
|
||||
private readonly MobileControlTouchpanelProperties localConfig;
|
||||
private IMobileControlRoomMessenger _bridge;
|
||||
|
||||
private string _appUrl;
|
||||
|
||||
public StringFeedback AppUrlFeedback { get; private set; }
|
||||
private readonly StringFeedback QrCodeUrlFeedback;
|
||||
private readonly StringFeedback McServerUrlFeedback;
|
||||
private readonly StringFeedback UserCodeFeedback;
|
||||
|
||||
private readonly BoolFeedback _appOpenFeedback;
|
||||
|
||||
public BoolFeedback AppOpenFeedback => _appOpenFeedback;
|
||||
|
||||
private readonly BoolFeedback _zoomIncomingCallFeedback;
|
||||
|
||||
public BoolFeedback ZoomIncomingCallFeedback => _zoomIncomingCallFeedback;
|
||||
|
||||
private readonly BoolFeedback _zoomInCallFeedback;
|
||||
|
||||
public event DeviceInfoChangeHandler DeviceInfoChanged;
|
||||
|
||||
public BoolFeedback ZoomInCallFeedback => _zoomInCallFeedback;
|
||||
|
||||
|
||||
public FeedbackCollection<Feedback> Feedbacks { get; private set; }
|
||||
|
||||
public FeedbackCollection<Feedback> ZoomFeedbacks { get; private set; }
|
||||
|
||||
public string DefaultRoomKey => _config.DefaultRoomKey;
|
||||
|
||||
public bool UseDirectServer => localConfig.UseDirectServer;
|
||||
|
||||
public bool ZoomRoomController => localConfig.ZoomRoomController;
|
||||
|
||||
public string Theme => localConfig.Theme;
|
||||
|
||||
public StringFeedback ThemeFeedback { get; private set; }
|
||||
|
||||
public DeviceInfo DeviceInfo => new DeviceInfo();
|
||||
|
||||
public MobileControlTouchpanelController(string key, string name, BasicTriListWithSmartObject panel, MobileControlTouchpanelProperties config) : base(key, name, panel, config)
|
||||
{
|
||||
localConfig = config;
|
||||
|
||||
AddPostActivationAction(SubscribeForMobileControlUpdates);
|
||||
|
||||
ThemeFeedback = new StringFeedback($"{Key}-theme", () => Theme);
|
||||
AppUrlFeedback = new StringFeedback($"{Key}-appUrl", () => _appUrl);
|
||||
QrCodeUrlFeedback = new StringFeedback($"{Key}-qrCodeUrl", () => _bridge?.QrCodeUrl);
|
||||
McServerUrlFeedback = new StringFeedback($"{Key}-mcServerUrl", () => _bridge?.McServerUrl);
|
||||
UserCodeFeedback = new StringFeedback($"{Key}-userCode", () => _bridge?.UserCode);
|
||||
|
||||
_appOpenFeedback = new BoolFeedback($"{Key}-appOpen", () =>
|
||||
{
|
||||
if (Panel is TswX60BaseClass tsX60)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, this, $"x60 sending {tsX60.ExtenderApplicationControlReservedSigs.HideOpenApplicationFeedback.BoolValue}");
|
||||
return !tsX60.ExtenderApplicationControlReservedSigs.HideOpenApplicationFeedback.BoolValue;
|
||||
}
|
||||
|
||||
if (Panel is TswX70Base tsX70)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, this, $"x70 sending {tsX70.ExtenderApplicationControlReservedSigs.HideOpenedApplicationFeedback.BoolValue}");
|
||||
return !tsX70.ExtenderApplicationControlReservedSigs.HideOpenedApplicationFeedback.BoolValue;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
_zoomIncomingCallFeedback = new BoolFeedback($"{Key}-zoomIncomingCall", () =>
|
||||
{
|
||||
if (Panel is TswX60WithZoomRoomAppReservedSigs tsX60)
|
||||
{
|
||||
return tsX60.ExtenderZoomRoomAppReservedSigs.ZoomRoomIncomingCallFeedback.BoolValue;
|
||||
}
|
||||
|
||||
if (Panel is TswX70Base tsX70)
|
||||
{
|
||||
return tsX70.ExtenderZoomRoomAppReservedSigs.ZoomRoomIncomingCallFeedback.BoolValue;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
_zoomInCallFeedback = new BoolFeedback($"{Key}-zoomInCall", () =>
|
||||
{
|
||||
if (Panel is TswX60WithZoomRoomAppReservedSigs tsX60)
|
||||
{
|
||||
return tsX60.ExtenderZoomRoomAppReservedSigs.ZoomRoomActiveFeedback.BoolValue;
|
||||
}
|
||||
|
||||
if (Panel is TswX70Base tsX70)
|
||||
{
|
||||
return tsX70.ExtenderZoomRoomAppReservedSigs.ZoomRoomActiveFeedback.BoolValue;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
Feedbacks = new FeedbackCollection<Feedback>
|
||||
{
|
||||
AppUrlFeedback, QrCodeUrlFeedback, McServerUrlFeedback, UserCodeFeedback
|
||||
};
|
||||
|
||||
ZoomFeedbacks = new FeedbackCollection<Feedback> {
|
||||
AppOpenFeedback, _zoomInCallFeedback, _zoomIncomingCallFeedback
|
||||
};
|
||||
|
||||
RegisterForExtenders();
|
||||
}
|
||||
|
||||
public void UpdateTheme(string theme)
|
||||
{
|
||||
localConfig.Theme = theme;
|
||||
|
||||
var props = JToken.FromObject(localConfig);
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault((d) => d.Key == Key);
|
||||
|
||||
if (deviceConfig == null) { return; }
|
||||
|
||||
deviceConfig.Properties = props;
|
||||
|
||||
ConfigWriter.UpdateDeviceConfig(deviceConfig);
|
||||
}
|
||||
|
||||
private void RegisterForExtenders()
|
||||
{
|
||||
if (Panel is TswXX70Base x70Panel)
|
||||
{
|
||||
x70Panel.ExtenderApplicationControlReservedSigs.DeviceExtenderSigChange += (e, a) =>
|
||||
{
|
||||
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();
|
||||
|
||||
if (!x70Panel.ExtenderApplicationControlReservedSigs.HideOpenedApplicationFeedback.BoolValue)
|
||||
{
|
||||
x70Panel.ExtenderButtonToolbarReservedSigs.ShowButtonToolbar();
|
||||
x70Panel.ExtenderButtonToolbarReservedSigs.Button2On();
|
||||
}
|
||||
else
|
||||
{
|
||||
x70Panel.ExtenderButtonToolbarReservedSigs.HideButtonToolbar();
|
||||
x70Panel.ExtenderButtonToolbarReservedSigs.Button2Off();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
x70Panel.ExtenderZoomRoomAppReservedSigs.DeviceExtenderSigChange += (e, a) =>
|
||||
{
|
||||
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)
|
||||
{
|
||||
ZoomIncomingCallFeedback.FireUpdate();
|
||||
}
|
||||
else if (a.Sig.Number == x70Panel.ExtenderZoomRoomAppReservedSigs.ZoomRoomActiveFeedback.Number)
|
||||
{
|
||||
ZoomInCallFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
x70Panel.ExtenderEthernetReservedSigs.DeviceExtenderSigChange += (e, a) =>
|
||||
{
|
||||
DeviceInfo.MacAddress = x70Panel.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
|
||||
DeviceInfo.IpAddress = x70Panel.ExtenderEthernetReservedSigs.IpAddressFeedback.StringValue;
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, this, $"MAC: {DeviceInfo.MacAddress} IP: {DeviceInfo.IpAddress}");
|
||||
|
||||
var handler = DeviceInfoChanged;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(this, new DeviceInfoEventArgs(DeviceInfo));
|
||||
};
|
||||
|
||||
x70Panel.ExtenderApplicationControlReservedSigs.Use();
|
||||
x70Panel.ExtenderZoomRoomAppReservedSigs.Use();
|
||||
x70Panel.ExtenderEthernetReservedSigs.Use();
|
||||
x70Panel.ExtenderButtonToolbarReservedSigs.Use();
|
||||
|
||||
x70Panel.ExtenderButtonToolbarReservedSigs.Button1Off();
|
||||
x70Panel.ExtenderButtonToolbarReservedSigs.Button3Off();
|
||||
x70Panel.ExtenderButtonToolbarReservedSigs.Button4Off();
|
||||
x70Panel.ExtenderButtonToolbarReservedSigs.Button5Off();
|
||||
x70Panel.ExtenderButtonToolbarReservedSigs.Button6Off();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Panel is TswX60WithZoomRoomAppReservedSigs x60withZoomApp)
|
||||
{
|
||||
x60withZoomApp.ExtenderApplicationControlReservedSigs.DeviceExtenderSigChange += (e, a) =>
|
||||
{
|
||||
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)
|
||||
{
|
||||
AppOpenFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
x60withZoomApp.ExtenderZoomRoomAppReservedSigs.DeviceExtenderSigChange += (e, a) =>
|
||||
{
|
||||
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)
|
||||
{
|
||||
ZoomIncomingCallFeedback.FireUpdate();
|
||||
}
|
||||
else if (a.Sig.Number == x60withZoomApp.ExtenderZoomRoomAppReservedSigs.ZoomRoomActiveFeedback.Number)
|
||||
{
|
||||
ZoomInCallFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
x60withZoomApp.ExtenderEthernetReservedSigs.DeviceExtenderSigChange += (e, a) =>
|
||||
{
|
||||
DeviceInfo.MacAddress = x60withZoomApp.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
|
||||
DeviceInfo.IpAddress = x60withZoomApp.ExtenderEthernetReservedSigs.IpAddressFeedback.StringValue;
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, this, $"MAC: {DeviceInfo.MacAddress} IP: {DeviceInfo.IpAddress}");
|
||||
|
||||
var handler = DeviceInfoChanged;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(this, new DeviceInfoEventArgs(DeviceInfo));
|
||||
};
|
||||
|
||||
x60withZoomApp.ExtenderZoomRoomAppReservedSigs.Use();
|
||||
x60withZoomApp.ExtenderApplicationControlReservedSigs.Use();
|
||||
x60withZoomApp.ExtenderEthernetReservedSigs.Use();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
var appMessenger = new ITswAppControlMessenger($"appControlMessenger-{Key}", $"/device/{Key}", this);
|
||||
|
||||
var zoomMessenger = new ITswZoomControlMessenger($"zoomControlMessenger-{Key}", $"/device/{Key}", this);
|
||||
|
||||
var themeMessenger = new ThemeMessenger($"themeMessenger-{Key}", $"/device/{Key}", this);
|
||||
|
||||
var mc = DeviceManager.AllDevices.OfType<IMobileControl>().FirstOrDefault();
|
||||
|
||||
if (mc == null)
|
||||
{
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
if (!(Panel is TswXX70Base) && !(Panel is TswX60WithZoomRoomAppReservedSigs))
|
||||
{
|
||||
mc.AddDeviceMessenger(themeMessenger);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
mc.AddDeviceMessenger(appMessenger);
|
||||
mc.AddDeviceMessenger(zoomMessenger);
|
||||
mc.AddDeviceMessenger(themeMessenger);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
|
||||
protected override void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, this, $"System Device Extender args: ${args.Event}:${args.Sig}");
|
||||
}
|
||||
|
||||
protected override void SetupPanelDrivers(string roomKey)
|
||||
{
|
||||
AppUrlFeedback.LinkInputSig(Panel.StringInput[1]);
|
||||
QrCodeUrlFeedback.LinkInputSig(Panel.StringInput[2]);
|
||||
McServerUrlFeedback.LinkInputSig(Panel.StringInput[3]);
|
||||
UserCodeFeedback.LinkInputSig(Panel.StringInput[4]);
|
||||
|
||||
Panel.OnlineStatusChange += (sender, args) =>
|
||||
{
|
||||
UpdateFeedbacks();
|
||||
|
||||
this.LogInformation("Sending {appUrl} on join 1", AppUrlFeedback.StringValue);
|
||||
|
||||
Panel.StringInput[1].StringValue = AppUrlFeedback.StringValue;
|
||||
Panel.StringInput[2].StringValue = QrCodeUrlFeedback.StringValue;
|
||||
Panel.StringInput[3].StringValue = McServerUrlFeedback.StringValue;
|
||||
Panel.StringInput[4].StringValue = UserCodeFeedback.StringValue;
|
||||
};
|
||||
}
|
||||
|
||||
private void SubscribeForMobileControlUpdates()
|
||||
{
|
||||
foreach (var dev in DeviceManager.AllDevices)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, this, $"{dev.Key}:{dev.GetType().Name}");
|
||||
}
|
||||
|
||||
var mcList = DeviceManager.AllDevices.OfType<MobileControlSystemController>().ToList();
|
||||
|
||||
if (mcList.Count == 0)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, this, $"No Mobile Control controller found");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// use first in list, since there should only be one.
|
||||
var mc = mcList[0];
|
||||
|
||||
var bridge = mc.GetRoomBridge(_config.DefaultRoomKey);
|
||||
|
||||
if (bridge == null)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, this, $"No Mobile Control bridge for {_config.DefaultRoomKey} found ");
|
||||
return;
|
||||
}
|
||||
|
||||
_bridge = bridge;
|
||||
|
||||
_bridge.UserCodeChanged += UpdateFeedbacks;
|
||||
_bridge.AppUrlChanged += (s, a) =>
|
||||
{
|
||||
this.LogInformation("AppURL changed");
|
||||
SetAppUrl(_bridge.AppUrl);
|
||||
UpdateFeedbacks(s, a);
|
||||
};
|
||||
|
||||
SetAppUrl(_bridge.AppUrl);
|
||||
}
|
||||
|
||||
public void SetAppUrl(string url)
|
||||
{
|
||||
_appUrl = url;
|
||||
AppUrlFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
private void UpdateFeedbacks(object sender, EventArgs args)
|
||||
{
|
||||
UpdateFeedbacks();
|
||||
}
|
||||
|
||||
private void UpdateFeedbacks()
|
||||
{
|
||||
foreach (var feedback in Feedbacks) { this.LogDebug("Updating {feedbackKey}", feedback.Key); feedback.FireUpdate(); }
|
||||
}
|
||||
|
||||
private void UpdateZoomFeedbacks()
|
||||
{
|
||||
foreach (var feedback in ZoomFeedbacks)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, this, $"Updating {feedback.Key}");
|
||||
feedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void HideOpenApp()
|
||||
{
|
||||
if (Panel is TswX70Base x70Panel)
|
||||
{
|
||||
x70Panel.ExtenderApplicationControlReservedSigs.HideOpenedApplication();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Panel is TswX60BaseClass x60Panel)
|
||||
{
|
||||
x60Panel.ExtenderApplicationControlReservedSigs.HideOpenApplication();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenApp()
|
||||
{
|
||||
if (Panel is TswX70Base x70Panel)
|
||||
{
|
||||
x70Panel.ExtenderApplicationControlReservedSigs.OpenApplication();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Panel is TswX60WithZoomRoomAppReservedSigs)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, this, $"X60 panel does not support zoom app");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseOpenApp()
|
||||
{
|
||||
if (Panel is TswX70Base x70Panel)
|
||||
{
|
||||
x70Panel.ExtenderApplicationControlReservedSigs.CloseOpenedApplication();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Panel is TswX60WithZoomRoomAppReservedSigs x60Panel)
|
||||
{
|
||||
x60Panel.ExtenderApplicationControlReservedSigs.CloseOpenedApplication();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void EndZoomCall()
|
||||
{
|
||||
if (Panel is TswX70Base x70Panel)
|
||||
{
|
||||
x70Panel.ExtenderZoomRoomAppReservedSigs.ZoomRoomEndCall();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Panel is TswX60WithZoomRoomAppReservedSigs x60Panel)
|
||||
{
|
||||
x60Panel.ExtenderZoomRoomAppReservedSigs.ZoomRoomEndCall();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateDeviceInfo()
|
||||
{
|
||||
if (Panel is TswXX70Base x70Panel)
|
||||
{
|
||||
DeviceInfo.MacAddress = x70Panel.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
|
||||
DeviceInfo.IpAddress = x70Panel.ExtenderEthernetReservedSigs.IpAddressFeedback.StringValue;
|
||||
|
||||
var handler = DeviceInfoChanged;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(this, new DeviceInfoEventArgs(DeviceInfo));
|
||||
}
|
||||
|
||||
if (Panel is TswX60WithZoomRoomAppReservedSigs x60Panel)
|
||||
{
|
||||
DeviceInfo.MacAddress = x60Panel.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
|
||||
DeviceInfo.IpAddress = x60Panel.ExtenderEthernetReservedSigs.IpAddressFeedback.StringValue;
|
||||
|
||||
var handler = DeviceInfoChanged;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(this, new DeviceInfoEventArgs(DeviceInfo));
|
||||
}
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, this, $"MAC: {DeviceInfo.MacAddress} IP: {DeviceInfo.IpAddress}");
|
||||
}
|
||||
}
|
||||
|
||||
public class MobileControlTouchpanelControllerFactory : EssentialsPluginDeviceFactory<MobileControlTouchpanelController>
|
||||
{
|
||||
public MobileControlTouchpanelControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "mccrestronapp", "mctsw550", "mctsw750", "mctsw1050", "mctsw560", "mctsw760", "mctsw1060", "mctsw570", "mctsw770", "mcts770", "mctsw1070", "mcts1070", "mcxpanel" };
|
||||
MinimumEssentialsFrameworkVersion = "2.0.0";
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
var comm = CommFactory.GetControlPropertiesConfig(dc);
|
||||
var props = JsonConvert.DeserializeObject<MobileControlTouchpanelProperties>(dc.Properties.ToString());
|
||||
|
||||
var panel = GetPanelForType(dc.Type, comm.IpIdInt, props.ProjectName);
|
||||
|
||||
if (panel == null)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Unable to create Touchpanel for type {0}. Touchpanel Controller WILL NOT function correctly", dc.Type);
|
||||
}
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Factory Attempting to create new MobileControlTouchpanelController");
|
||||
|
||||
var panelController = new MobileControlTouchpanelController(dc.Key, dc.Name, panel, props);
|
||||
|
||||
return panelController;
|
||||
}
|
||||
|
||||
private BasicTriListWithSmartObject GetPanelForType(string type, uint id, string projectName)
|
||||
{
|
||||
type = type.ToLower().Replace("mc", "");
|
||||
try
|
||||
{
|
||||
if (type == "crestronapp")
|
||||
{
|
||||
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
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user