docs: XML comments for Devices.Common

This commit is contained in:
Andrew Welker
2025-10-09 13:18:36 -05:00
parent a5d409e93a
commit f9d9df9d5c
115 changed files with 5772 additions and 4292 deletions

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
@@ -17,48 +13,68 @@ namespace PepperDash.Essentials.Devices.Common
/// </summary>
public class GenericAudioOut : EssentialsDevice, IRoutingSink
{
public RoutingInputPort CurrentInputPort => AnyAudioIn;
/// <summary>
/// Gets the current input port
/// </summary>
public RoutingInputPort CurrentInputPort => AnyAudioIn;
public event SourceInfoChangeHandler CurrentSourceChange;
/// <summary>
/// Event fired when the current source changes
/// </summary>
public event SourceInfoChangeHandler CurrentSourceChange;
public string CurrentSourceInfoKey { get; set; }
public SourceListItem CurrentSourceInfo
{
get
{
return _CurrentSourceInfo;
}
set
{
if (value == _CurrentSourceInfo) return;
/// <summary>
/// Gets or sets the current source info key
/// </summary>
public string CurrentSourceInfoKey { get; set; }
/// <summary>
/// Gets or sets the current source info
/// </summary>
public SourceListItem CurrentSourceInfo
{
get
{
return _CurrentSourceInfo;
}
set
{
if (value == _CurrentSourceInfo) return;
var handler = CurrentSourceChange;
var handler = CurrentSourceChange;
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.WillChange);
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.WillChange);
_CurrentSourceInfo = value;
_CurrentSourceInfo = value;
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.DidChange);
}
}
SourceListItem _CurrentSourceInfo;
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.DidChange);
}
}
SourceListItem _CurrentSourceInfo;
/// <summary>
/// Gets or sets the AnyAudioIn
/// </summary>
/// <summary>
/// Gets or sets the AnyAudioIn
/// </summary>
public RoutingInputPort AnyAudioIn { get; private set; }
/// <summary>
/// Constructor for GenericAudioOut
/// </summary>
/// <param name="key">Device key</param>
/// <param name="name">Device name</param>
public GenericAudioOut(string key, string name)
: base(key, name)
{
AnyAudioIn = new RoutingInputPort(RoutingPortNames.AnyAudioIn, eRoutingSignalType.Audio,
AnyAudioIn = new RoutingInputPort(RoutingPortNames.AnyAudioIn, eRoutingSignalType.Audio,
eRoutingPortConnectionType.LineAudio, null, this);
}
#region IRoutingInputs Members
/// <summary>
/// Gets the collection of input ports
/// </summary>
public RoutingPortCollection<RoutingInputPort> InputPorts
{
get { return new RoutingPortCollection<RoutingInputPort> { AnyAudioIn }; }
@@ -68,23 +84,32 @@ namespace PepperDash.Essentials.Devices.Common
}
/// <summary>
/// Represents a GenericAudioOutWithVolume
/// </summary>
/// <summary>
/// Represents a GenericAudioOutWithVolume
/// </summary>
public class GenericAudioOutWithVolume : GenericAudioOut, IHasVolumeDevice
{
/// <summary>
/// Gets the volume device key
/// </summary>
public string VolumeDeviceKey { get; private set; }
/// <summary>
/// Gets the volume zone
/// </summary>
public uint VolumeZone { get; private set; }
/// <summary>
/// Gets the volume device
/// </summary>
public IBasicVolumeControls VolumeDevice
{
{
get
{
var dev = DeviceManager.GetDeviceForKey(VolumeDeviceKey);
if (dev is IAudioZones)
return (dev as IAudioZones).Zone[VolumeZone];
else return dev as IBasicVolumeControls;
}
}
}
/// <summary>
@@ -103,24 +128,30 @@ namespace PepperDash.Essentials.Devices.Common
}
public class GenericAudioOutWithVolumeFactory : EssentialsDeviceFactory<GenericAudioOutWithVolume>
{
public GenericAudioOutWithVolumeFactory()
{
TypeNames = new List<string>() { "genericaudiooutwithvolume" };
}
/// <summary>
/// Factory for creating GenericAudioOutWithVolume devices
/// </summary>
public class GenericAudioOutWithVolumeFactory : EssentialsDeviceFactory<GenericAudioOutWithVolume>
{
/// <summary>
/// Constructor for GenericAudioOutWithVolumeFactory
/// </summary>
public GenericAudioOutWithVolumeFactory()
{
TypeNames = new List<string>() { "genericaudiooutwithvolume" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new GenericAudioOutWithVolumeFactory Device");
var zone = dc.Properties.Value<uint>("zone");
return new GenericAudioOutWithVolume(dc.Key, dc.Name,
dc.Properties.Value<string>("volumeDeviceKey"), zone);
}
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new GenericAudioOutWithVolumeFactory Device");
var zone = dc.Properties.Value<uint>("zone");
return new GenericAudioOutWithVolume(dc.Key, dc.Name,
dc.Properties.Value<string>("volumeDeviceKey"), zone);
}
}
}

View File

@@ -1,18 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.Devices.Common.AudioCodec
{
/// <summary>
/// Abstract base class for audio codec devices
/// </summary>
public abstract class AudioCodecBase : EssentialsDevice, IHasDialer, IUsageTracking, IAudioCodecInfo
{
/// <summary>
/// Event fired when call status changes
/// </summary>
public event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
/// <summary>
@@ -52,6 +54,11 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
/// </summary>
public List<CodecActiveCallItem> ActiveCalls { get; set; }
/// <summary>
/// Constructor for AudioCodecBase
/// </summary>
/// <param name="key">Device key</param>
/// <param name="name">Device name</param>
public AudioCodecBase(string key, string name)
: base(key, name)
{
@@ -70,11 +77,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
}
/// <summary>
///
/// Handles call status change events
/// </summary>
/// <param name="previousStatus"></param>
/// <param name="newStatus"></param>
/// <param name="item"></param>
/// <param name="item">The call item that changed status</param>
protected void OnCallStatusChange(CodecActiveCallItem item)
{
var handler = CallStatusChange;
@@ -92,16 +97,22 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
#region IHasDialer Members
/// <inheritdoc />
public abstract void Dial(string number);
/// <inheritdoc />
public abstract void EndCall(CodecActiveCallItem activeCall);
/// <inheritdoc />
public abstract void EndAllCalls();
/// <inheritdoc />
public abstract void AcceptCall(CodecActiveCallItem item);
/// <inheritdoc />
public abstract void RejectCall(CodecActiveCallItem item);
/// <inheritdoc />
public abstract void SendDtmf(string digit);
#endregion

View File

@@ -1,16 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.AudioCodec
namespace PepperDash.Essentials.Devices.Common.AudioCodec
{
/// <summary>
/// Implements a common set of data about a codec
/// </summary>
public interface IAudioCodecInfo
{
/// <summary>
/// Gets the codec information
/// </summary>
AudioCodecInfo CodecInfo { get; }
}
@@ -19,6 +16,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
/// </summary>
public abstract class AudioCodecInfo
{
/// <summary>
/// Gets or sets the phone number
/// </summary>
public abstract string PhoneNumber { get; set; }
}
}

View File

@@ -1,23 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.AudioCodec
{
/// <summary>
/// For rooms that have audio codec
/// </summary>
public interface IHasAudioCodec:IHasInCallFeedback
public interface IHasAudioCodec : IHasInCallFeedback
{
/// <summary>
/// Gets the audio codec device
/// </summary>
AudioCodecBase AudioCodec { get; }
/// <summary>
/// Make this more specific
/// </summary>
//List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem> ActiveCalls { get; }
}
}

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
@@ -17,6 +13,12 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
/// </summary>
public class MockAC : AudioCodecBase
{
/// <summary>
/// Constructor for MockAC
/// </summary>
/// <param name="key">Device key</param>
/// <param name="name">Device name</param>
/// <param name="props">MockAC properties configuration</param>
public MockAC(string key, string name, MockAcPropertiesConfig props)
: base(key, name)
{
@@ -109,13 +111,10 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
Debug.LogMessage(LogEventLevel.Debug, this, "BEEP BOOP SendDTMF: {0}", s);
}
/// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <summary>
/// TestIncomingAudioCall method
/// </summary>
/// <param name="number">Phone number to call from</param>
public void TestIncomingAudioCall(string number)
{
Debug.LogMessage(LogEventLevel.Debug, this, "TestIncomingAudioCall from {0}", number);
@@ -133,6 +132,7 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
{
string _phoneNumber;
/// <inheritdoc />
public override string PhoneNumber
{
get
@@ -151,6 +151,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
/// </summary>
public class MockACFactory : EssentialsDeviceFactory<MockAC>
{
/// <summary>
/// Constructor for MockACFactory
/// </summary>
public MockACFactory()
{
TypeNames = new List<string>() { "mockac" };

View File

@@ -1,12 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.AudioCodec
{
@@ -15,10 +7,10 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
/// </summary>
public class MockAcPropertiesConfig
{
[JsonProperty("phoneNumber")]
/// <summary>
/// Gets or sets the PhoneNumber
/// </summary>
[JsonProperty("phoneNumber")]
public string PhoneNumber { get; set; }
}
}

View File

@@ -3,20 +3,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using System.Reflection;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.Presets;
using PepperDash.Essentials.Devices.Common.Codec;
using Newtonsoft.Json;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Cameras
@@ -26,31 +20,52 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
/// </summary>
public enum eCameraCapabilities
{
/// <summary>
/// No camera capabilities
/// </summary>
None = 0,
/// <summary>
/// Camera supports pan movement
/// </summary>
Pan = 1,
Tilt = 2,
/// <summary>
/// Camera supports tilt movement
/// </summary>
Tilt = 2,
/// <summary>
/// Camera supports zoom functionality
/// </summary>
Zoom = 4,
/// <summary>
/// Camera supports focus adjustment
/// </summary>
Focus = 8
}
/// <summary>
/// Abstract base class for camera devices that provides common camera functionality and capabilities
/// </summary>
public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs
{
[JsonProperty("controlMode", NullValueHandling = NullValueHandling.Ignore)]
{
/// <summary>
/// Gets or sets the ControlMode
/// </summary>
[JsonProperty("controlMode", NullValueHandling = NullValueHandling.Ignore)]
public eCameraControlMode ControlMode { get; protected set; }
#region IRoutingOutputs Members
[JsonIgnore]
/// <summary>
/// Gets or sets the OutputPorts
/// </summary>
[JsonIgnore]
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; protected set; }
#endregion
/// <summary>
/// Gets a value indicating whether this camera supports pan movement
/// </summary>
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
public bool CanPan
{
@@ -59,6 +74,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
return (Capabilities & eCameraCapabilities.Pan) == eCameraCapabilities.Pan;
}
}
/// <summary>
/// Gets a value indicating whether this camera supports tilt movement
/// </summary>
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
public bool CanTilt
{
@@ -67,6 +86,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
return (Capabilities & eCameraCapabilities.Tilt) == eCameraCapabilities.Tilt;
}
}
/// <summary>
/// Gets a value indicating whether this camera supports zoom functionality
/// </summary>
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
public bool CanZoom
{
@@ -75,6 +98,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
return (Capabilities & eCameraCapabilities.Zoom) == eCameraCapabilities.Zoom;
}
}
/// <summary>
/// Gets a value indicating whether this camera supports focus adjustment
/// </summary>
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
public bool CanFocus
{
@@ -84,23 +111,42 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
}
}
// A bitmasked value to indicate the movement capabilites of this camera
/// <summary>
/// Gets or sets a bitmasked value to indicate the movement capabilities of this camera
/// </summary>
protected eCameraCapabilities Capabilities { get; set; }
protected CameraBase(DeviceConfig config) : base(config)
{
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
ControlMode = eCameraControlMode.Manual;
}
protected CameraBase(string key, string name) :
this (new DeviceConfig{Name = name, Key = key})
/// <summary>
/// Initializes a new instance of the CameraBase class with the specified device configuration
/// </summary>
/// <param name="config">The device configuration</param>
protected CameraBase(DeviceConfig config) : base(config)
{
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
ControlMode = eCameraControlMode.Manual;
}
/// <summary>
/// Initializes a new instance of the CameraBase class with the specified key and name
/// </summary>
/// <param name="key">The unique key for this camera device</param>
/// <param name="name">The friendly name for this camera device</param>
protected CameraBase(string key, string name) :
this(new DeviceConfig { Name = name, Key = key })
{
}
/// <summary>
/// Links the camera device to the API bridge for control and feedback
/// </summary>
/// <param name="cameraDevice">The camera device to link</param>
/// <param name="trilist">The trilist for communication</param>
/// <param name="joinStart">The starting join number for the camera controls</param>
/// <param name="joinMapKey">The join map key for custom join mappings</param>
/// <param name="bridge">The EiscApiAdvanced bridge for advanced join mapping</param>
protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
EiscApiAdvanced bridge)
{
@@ -240,13 +286,13 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
{
int tempNum = i;
trilist.SetSigTrueAction((ushort) (joinMap.PresetRecallStart.JoinNumber + tempNum), () =>
trilist.SetSigTrueAction((ushort)(joinMap.PresetRecallStart.JoinNumber + tempNum), () =>
{
presetsCamera.PresetSelect(tempNum);
});
trilist.SetSigTrueAction((ushort) (joinMap.PresetSaveStart.JoinNumber + tempNum), () =>
trilist.SetSigTrueAction((ushort)(joinMap.PresetSaveStart.JoinNumber + tempNum), () =>
{
var label = trilist.GetString((ushort) (joinMap.PresetLabelStart.JoinNumber + tempNum));
var label = trilist.GetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum));
presetsCamera.PresetStore(tempNum, label);
});
@@ -277,7 +323,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label);
}
}
}
}
/// <summary>
@@ -285,6 +331,13 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
/// </summary>
public class CameraPreset : PresetBase
{
/// <summary>
/// Initializes a new instance of the CameraPreset class
/// </summary>
/// <param name="id">The preset ID</param>
/// <param name="description">The preset description</param>
/// <param name="isDefined">Whether the preset is defined</param>
/// <param name="isDefinable">Whether the preset can be defined</param>
public CameraPreset(int id, string description, bool isDefined, bool isDefinable)
: base(id, description, isDefined, isDefinable)
{
@@ -293,37 +346,37 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
}
/// <summary>
/// Represents a CameraPropertiesConfig
/// </summary>
public class CameraPropertiesConfig
{
/// <summary>
/// Gets or sets the CommunicationMonitorProperties
/// </summary>
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
/// <summary>
/// Represents a CameraPropertiesConfig
/// </summary>
public class CameraPropertiesConfig
{
/// <summary>
/// Gets or sets the CommunicationMonitorProperties
/// </summary>
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
/// <summary>
/// Gets or sets the Control
/// </summary>
public ControlPropertiesConfig Control { get; set; }
/// <summary>
/// Gets or sets the Control
/// </summary>
public ControlPropertiesConfig Control { get; set; }
[JsonProperty("supportsAutoMode")]
/// <summary>
/// Gets or sets the SupportsAutoMode
/// </summary>
[JsonProperty("supportsAutoMode")]
public bool SupportsAutoMode { get; set; }
[JsonProperty("supportsOffMode")]
/// <summary>
/// Gets or sets the SupportsOffMode
/// </summary>
[JsonProperty("supportsOffMode")]
public bool SupportsOffMode { get; set; }
[JsonProperty("presets")]
/// <summary>
/// Gets or sets the Presets
/// </summary>
[JsonProperty("presets")]
public List<CameraPreset> Presets { get; set; }
}
}
}

View File

@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;

View File

@@ -3,38 +3,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Devices.Common.Codec;
using System.Text.RegularExpressions;
using System.Reflection;
using Newtonsoft.Json;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Represents a CameraVisca
/// </summary>
public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IHasPowerControlWithFeedback, IBridgeAdvanced, IHasCameraFocusControl, IHasAutoFocusMode
{
/// <summary>
/// Represents a CameraVisca
/// </summary>
public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IHasPowerControlWithFeedback, IBridgeAdvanced, IHasCameraFocusControl, IHasAutoFocusMode
{
private readonly CameraViscaPropertiesConfig PropertiesConfig;
/// <summary>
/// Gets or sets the Communication
/// </summary>
public IBasicCommunication Communication { get; private set; }
/// <summary>
/// Gets or sets the Communication
/// </summary>
public IBasicCommunication Communication { get; private set; }
/// <summary>
/// Gets or sets the CommunicationMonitor
/// </summary>
public StatusMonitorBase CommunicationMonitor { get; private set; }
/// <summary>
/// Gets or sets the CommunicationMonitor
/// </summary>
public StatusMonitorBase CommunicationMonitor { get; private set; }
/// <summary>
/// Used to store the actions to parse inquiry responses as the inquiries are sent
@@ -45,20 +40,41 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
/// Camera ID (Default 1)
/// </summary>
public byte ID = 0x01;
/// <summary>
/// Response ID used for VISCA communication
/// </summary>
public byte ResponseID;
/// <summary>
/// Slow speed value for pan movement
/// </summary>
public byte PanSpeedSlow = 0x10;
public byte PanSpeedSlow = 0x10;
public byte TiltSpeedSlow = 0x10;
/// <summary>
/// Slow speed value for tilt movement
/// </summary>
public byte TiltSpeedSlow = 0x10;
/// <summary>
/// Fast speed value for pan movement
/// </summary>
public byte PanSpeedFast = 0x13;
/// <summary>
/// Fast speed value for tilt movement
/// </summary>
public byte TiltSpeedFast = 0x13;
// private bool IsMoving;
private bool IsZooming;
private bool IsZooming;
bool _powerIsOn;
public bool PowerIsOn
/// <summary>
/// Gets or sets a value indicating whether the camera power is on
/// </summary>
public bool PowerIsOn
{
get
{
@@ -87,12 +103,23 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
long FastSpeedHoldTimeMs = 2000;
byte[] IncomingBuffer = new byte[] { };
public BoolFeedback PowerIsOnFeedback { get; private set; }
byte[] IncomingBuffer = new byte[] { };
/// <summary>
/// Feedback indicating whether the camera power is on
/// </summary>
public BoolFeedback PowerIsOnFeedback { get; private set; }
/// <summary>
/// Initializes a new instance of the CameraVisca class
/// </summary>
/// <param name="key">The unique key for this camera device</param>
/// <param name="name">The friendly name for this camera device</param>
/// <param name="comm">The communication interface for VISCA protocol</param>
/// <param name="props">The camera properties configuration</param>
public CameraVisca(string key, string name, IBasicCommunication comm, CameraViscaPropertiesConfig props) :
base(key, name)
{
base(key, name)
{
InquiryResponseQueue = new CrestronQueue<Action<byte[]>>(15);
Presets = props.Presets;
@@ -107,8 +134,8 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
OutputPorts.Add(new RoutingOutputPort("videoOut", eRoutingSignalType.Video, eRoutingPortConnectionType.None, null, this, true));
// Default to all capabilties
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom | eCameraCapabilities.Focus;
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom | eCameraCapabilities.Focus;
Communication = comm;
if (comm is ISocketStatus socket)
{
@@ -121,19 +148,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
}
Communication.BytesReceived += new EventHandler<GenericCommMethodReceiveBytesArgs>(Communication_BytesReceived);
PowerIsOnFeedback = new BoolFeedback(() => { return PowerIsOn; });
CameraIsOffFeedback = new BoolFeedback(() => { return !PowerIsOn; });
PowerIsOnFeedback = new BoolFeedback("powerIsOn", () => { return PowerIsOn; });
CameraIsOffFeedback = new BoolFeedback("cameraIsOff", () => { return !PowerIsOn; });
if (props.CommunicationMonitorProperties != null)
{
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
}
else
{
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 20000, 120000, 300000, "\x81\x09\x04\x00\xFF");
}
DeviceManager.AddDevice(CommunicationMonitor);
}
if (props.CommunicationMonitorProperties != null)
{
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
}
else
{
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 20000, 120000, 300000, "\x81\x09\x04\x00\xFF");
}
DeviceManager.AddDevice(CommunicationMonitor);
}
/// <summary>
@@ -165,57 +192,57 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
}
}
/// <summary>
/// CustomActivate method
/// </summary>
/// <inheritdoc />
public override bool CustomActivate()
{
Communication.Connect();
CommunicationMonitor.StatusChange += (o, a) => { Debug.LogMessage(LogEventLevel.Verbose, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
CommunicationMonitor.Start();
/// <summary>
/// CustomActivate method
/// </summary>
/// <inheritdoc />
public override bool CustomActivate()
{
Communication.Connect();
CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
return true;
}
CommunicationMonitor.StatusChange += (o, a) => { Debug.LogMessage(LogEventLevel.Verbose, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
CommunicationMonitor.Start();
/// <summary>
/// LinkToApi method
/// </summary>
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge);
}
void Socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
{
Debug.LogMessage(LogEventLevel.Verbose, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString());
CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
return true;
}
if (e.Client.IsConnected)
{
}
else
{
/// <summary>
/// LinkToApi method
/// </summary>
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge);
}
}
}
void Socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
{
Debug.LogMessage(LogEventLevel.Verbose, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString());
void SendBytes(byte[] b)
{
if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
Debug.LogMessage(LogEventLevel.Verbose, this, "Sending:{0}", ComTextHelper.GetEscapedText(b));
if (e.Client.IsConnected)
{
Communication.SendBytes(b);
}
}
else
{
void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
{
}
}
void SendBytes(byte[] b)
{
if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
Debug.LogMessage(LogEventLevel.Verbose, this, "Sending:{0}", ComTextHelper.GetEscapedText(b));
Communication.SendBytes(b);
}
void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
{
var newBytes = new byte[IncomingBuffer.Length + e.Bytes.Length];
try
@@ -355,10 +382,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
/// <summary>
/// Sends a pan/tilt command. If the command is not for fastSpeed then it starts a timer to initiate fast speed.
/// </summary>
/// <param name="cmd"></param>
/// <param name="fastSpeed"></param>
private void SendPanTiltCommand (byte[] cmd, bool fastSpeedEnabled)
{
/// <param name="cmd">The VISCA command to send</param>
/// <param name="fastSpeedEnabled">Whether fast speed is enabled for this command</param>
private void SendPanTiltCommand(byte[] cmd, bool fastSpeedEnabled)
{
SendBytes(GetPanTiltCommand(cmd, fastSpeedEnabled));
if (!fastSpeedEnabled)
@@ -372,7 +399,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
SpeedTimer = new CTimer((o) => SendPanTiltCommand(GetPanTiltCommand(cmd, true), true), FastSpeedHoldTimeMs);
}
}
}
private void StopSpeedTimer()
{
@@ -381,7 +408,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
SpeedTimer.Stop();
SpeedTimer.Dispose();
SpeedTimer = null;
}
}
}
/// <summary>
@@ -424,14 +451,14 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
InquiryResponseQueue.Enqueue(HandlePowerResponse);
}
/// <summary>
/// PowerOn method
/// </summary>
public void PowerOn()
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x02, 0xFF });
/// <summary>
/// PowerOn method
/// </summary>
public void PowerOn()
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x02, 0xFF });
SendPowerQuery();
}
}
void HandlePowerResponse(byte[] response)
{
@@ -450,12 +477,12 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
}
}
/// <summary>
/// PowerOff method
/// </summary>
public void PowerOff()
{
SendBytes(new byte[] {ID, 0x01, 0x04, 0x00, 0x03, 0xFF});
/// <summary>
/// PowerOff method
/// </summary>
public void PowerOff()
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x03, 0xFF });
SendPowerQuery();
}
@@ -470,22 +497,22 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
PowerOn();
}
/// <summary>
/// PanLeft method
/// </summary>
public void PanLeft()
{
SendPanTiltCommand(new byte[] {0x01, 0x03}, false);
// IsMoving = true;
}
/// <summary>
/// PanRight method
/// </summary>
public void PanRight()
{
/// <summary>
/// PanLeft method
/// </summary>
public void PanLeft()
{
SendPanTiltCommand(new byte[] { 0x01, 0x03 }, false);
// IsMoving = true;
}
/// <summary>
/// PanRight method
/// </summary>
public void PanRight()
{
SendPanTiltCommand(new byte[] { 0x02, 0x03 }, false);
// IsMoving = true;
}
// IsMoving = true;
}
/// <summary>
/// PanStop method
/// </summary>
@@ -493,22 +520,22 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
{
Stop();
}
/// <summary>
/// TiltDown method
/// </summary>
public void TiltDown()
{
/// <summary>
/// TiltDown method
/// </summary>
public void TiltDown()
{
SendPanTiltCommand(new byte[] { 0x03, 0x02 }, false);
// IsMoving = true;
}
/// <summary>
/// TiltUp method
/// </summary>
public void TiltUp()
{
// IsMoving = true;
}
/// <summary>
/// TiltUp method
/// </summary>
public void TiltUp()
{
SendPanTiltCommand(new byte[] { 0x03, 0x01 }, false);
// IsMoving = true;
}
// IsMoving = true;
}
/// <summary>
/// TiltStop method
/// </summary>
@@ -517,28 +544,28 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
Stop();
}
private void SendZoomCommand (byte cmd)
{
SendBytes(new byte[] {ID, 0x01, 0x04, 0x07, cmd, 0xFF} );
}
private void SendZoomCommand(byte cmd)
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x07, cmd, 0xFF });
}
/// <summary>
/// ZoomIn method
/// </summary>
public void ZoomIn()
{
/// <summary>
/// ZoomIn method
/// </summary>
public void ZoomIn()
{
SendZoomCommand(ZoomInCmd);
IsZooming = true;
}
/// <summary>
/// ZoomOut method
/// </summary>
public void ZoomOut()
{
IsZooming = true;
}
/// <summary>
/// ZoomOut method
/// </summary>
public void ZoomOut()
{
SendZoomCommand(ZoomOutCmd);
IsZooming = true;
}
IsZooming = true;
}
/// <summary>
/// ZoomStop method
/// </summary>
@@ -547,23 +574,23 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
Stop();
}
/// <summary>
/// Stop method
/// </summary>
public void Stop()
{
if (IsZooming)
{
/// <summary>
/// Stop method
/// </summary>
public void Stop()
{
if (IsZooming)
{
SendZoomCommand(ZoomStopCmd);
IsZooming = false;
}
else
{
IsZooming = false;
}
else
{
StopSpeedTimer();
SendPanTiltCommand(new byte[] { 0x03, 0x03 }, false);
// IsMoving = false;
}
}
// IsMoving = false;
}
}
/// <summary>
/// PositionHome method
/// </summary>
@@ -572,33 +599,39 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
SendBytes(new byte[] { ID, 0x01, 0x06, 0x02, PanSpeedFast, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF });
SendBytes(new byte[] { ID, 0x01, 0x04, 0x47, 0x00, 0x00, 0x00, 0x00, 0xFF });
}
/// <summary>
/// RecallPreset method
/// </summary>
public void RecallPreset(int presetNumber)
{
SendBytes(new byte[] {ID, 0x01, 0x04, 0x3F, 0x02, (byte)presetNumber, 0xFF} );
}
/// <summary>
/// SavePreset method
/// </summary>
public void SavePreset(int presetNumber)
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF });
}
/// <summary>
/// RecallPreset method
/// </summary>
public void RecallPreset(int presetNumber)
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x02, (byte)presetNumber, 0xFF });
}
/// <summary>
/// SavePreset method
/// </summary>
public void SavePreset(int presetNumber)
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF });
}
#region IHasCameraPresets Members
/// <summary>
/// Event that is raised when the presets list has changed
/// </summary>
public event EventHandler<EventArgs> PresetsListHasChanged;
protected void OnPresetsListHasChanged()
{
var handler = PresetsListHasChanged;
if (handler == null)
return;
/// <summary>
/// Raises the PresetsListHasChanged event
/// </summary>
protected void OnPresetsListHasChanged()
{
var handler = PresetsListHasChanged;
if (handler == null)
return;
handler.Invoke(this, EventArgs.Empty);
}
handler.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Gets or sets the Presets
@@ -741,6 +774,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
/// </summary>
public class CameraViscaFactory : EssentialsDeviceFactory<CameraVisca>
{
/// <summary>
/// Initializes a new instance of the CameraViscaFactory class
/// </summary>
public CameraViscaFactory()
{
TypeNames = new List<string>() { "cameravisca" };
@@ -768,11 +804,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
{
/// <summary>
/// Control ID of the camera (1-7)
/// </summary>
[JsonProperty("id")]
/// <summary>
/// Gets or sets the Id
/// </summary>
[JsonProperty("id")]
public uint Id { get; set; }
/// <summary>
@@ -790,7 +824,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
/// <summary>
/// Slow tilt speed (0-18)
/// </summary>
[JsonProperty("tiltSpeedSlow")]
[JsonProperty("tiltSpeedSlow")]
public uint TiltSpeedSlow { get; set; }
/// <summary>

View File

@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
@@ -11,12 +8,27 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
/// </summary>
public interface IHasCameraPresets
{
/// <summary>
/// Event that is raised when the presets list has changed
/// </summary>
event EventHandler<EventArgs> PresetsListHasChanged;
/// <summary>
/// Gets the list of camera presets
/// </summary>
List<CameraPreset> Presets { get; }
/// <summary>
/// Selects the specified preset
/// </summary>
/// <param name="preset">The preset number to select</param>
void PresetSelect(int preset);
/// <summary>
/// Stores a preset at the specified location with the given description
/// </summary>
/// <param name="preset">The preset number to store</param>
/// <param name="description">The description for the preset</param>
void PresetStore(int preset, string description);
}
}

View File

@@ -0,0 +1,26 @@
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents a Call
/// </summary>
public class Call
{
/// <summary>
/// Gets or sets the Number
/// </summary>
public string Number { get; set; }
/// <summary>
/// Gets or sets the Protocol
/// </summary>
public string Protocol { get; set; }
/// <summary>
/// Gets or sets the CallRate
/// </summary>
public string CallRate { get; set; }
/// <summary>
/// Gets or sets the CallType
/// </summary>
public string CallType { get; set; }
}
}

View File

@@ -1,10 +1,5 @@
using PepperDash.Core;
using PepperDash.Essentials.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PepperDash.Essentials.Devices.Common.Codec.Cisco
{

View File

@@ -1,10 +1,5 @@
using PepperDash.Core;
using PepperDash.Essentials.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PepperDash.Essentials.Devices.Common.Codec.Cisco
{

View File

@@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
@@ -17,55 +13,55 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public class CodecActiveCallItem
{
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Name
/// </summary>
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }
[JsonProperty("number", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Number
/// </summary>
[JsonProperty("number", NullValueHandling = NullValueHandling.Ignore)]
public string Number { get; set; }
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
/// <summary>
/// Gets or sets the Type
/// </summary>
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
public eCodecCallType Type { get; set; }
[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
/// <summary>
/// Gets or sets the Status
/// </summary>
[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
public eCodecCallStatus Status { get; set; }
[JsonProperty("direction", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
/// <summary>
/// Gets or sets the Direction
/// </summary>
[JsonProperty("direction", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
public eCodecCallDirection Direction { get; set; }
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Id
/// </summary>
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
public string Id { get; set; }
[JsonProperty("isOnHold", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the IsOnHold
/// </summary>
[JsonProperty("isOnHold", NullValueHandling = NullValueHandling.Ignore)]
public bool IsOnHold { get; set; }
[JsonProperty("duration", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Duration
/// </summary>
[JsonProperty("duration", NullValueHandling = NullValueHandling.Ignore)]
public TimeSpan Duration { get; set; }
//public object CallMetaData { get; set; }
@@ -81,7 +77,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
{
return !(Status == eCodecCallStatus.Disconnected
|| Status == eCodecCallStatus.Disconnecting
|| Status == eCodecCallStatus.Idle
|| Status == eCodecCallStatus.Idle
|| Status == eCodecCallStatus.Unknown);
}
}
@@ -97,6 +93,10 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public CodecActiveCallItem CallItem { get; private set; }
/// <summary>
/// Initializes a new instance of the CodecCallStatusItemChangeEventArgs class
/// </summary>
/// <param name="item">The call item that changed</param>
public CodecCallStatusItemChangeEventArgs(CodecActiveCallItem item)
{
CallItem = item;

View File

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents a codec directory
/// </summary>
public class CodecDirectory
{
/// <summary>
/// Represents the contents of the directory
/// We don't want to serialize this for messages to MobileControl. MC can combine Contacts and Folders to get the same data
/// </summary>
[JsonIgnore]
public List<DirectoryItem> CurrentDirectoryResults { get; private set; }
/// <summary>
/// Gets the Contacts in the CurrentDirectoryResults
/// </summary>
[JsonProperty("contacts")]
public List<DirectoryItem> Contacts
{
get
{
return CurrentDirectoryResults.OfType<DirectoryContact>().Cast<DirectoryItem>().ToList();
}
}
/// <summary>
/// Gets the Folders in the CurrentDirectoryResults
/// </summary>
[JsonProperty("folders")]
public List<DirectoryItem> Folders
{
get
{
return CurrentDirectoryResults.OfType<DirectoryFolder>().Cast<DirectoryItem>().ToList();
}
}
/// <summary>
/// Used to store the ID of the current folder for CurrentDirectoryResults
/// Gets or sets the ResultsFolderId
/// </summary>
[JsonProperty("resultsFolderId")]
public string ResultsFolderId { get; set; }
/// <summary>
/// Constructor for <see cref="CodecDirectory"/>
/// </summary>
public CodecDirectory()
{
CurrentDirectoryResults = new List<DirectoryItem>();
}
/// <summary>
/// Adds folders to the directory
/// </summary>
/// <param name="folders"></param>
public void AddFoldersToDirectory(List<DirectoryItem> folders)
{
if (folders != null)
CurrentDirectoryResults.AddRange(folders);
SortDirectory();
}
/// <summary>
/// Adds contacts to the directory
/// </summary>
/// <param name="contacts"></param>
public void AddContactsToDirectory(List<DirectoryItem> contacts)
{
if (contacts != null)
CurrentDirectoryResults.AddRange(contacts);
SortDirectory();
}
/// <summary>
/// Filters the CurrentDirectoryResults by the predicate
/// </summary>
/// <param name="predicate"></param>
public void FilterContacts(Func<DirectoryItem, bool> predicate)
{
CurrentDirectoryResults = CurrentDirectoryResults.Where(predicate).ToList();
}
/// <summary>
/// Sorts the DirectoryResults list to display all folders alphabetically, then all contacts alphabetically
/// </summary>
private void SortDirectory()
{
var sortedFolders = new List<DirectoryItem>();
sortedFolders.AddRange(CurrentDirectoryResults.Where(f => f is DirectoryFolder));
sortedFolders.OrderBy(f => f.Name);
var sortedContacts = new List<DirectoryItem>();
sortedContacts.AddRange(CurrentDirectoryResults.Where(c => c is DirectoryContact));
sortedFolders.OrderBy(c => c.Name);
CurrentDirectoryResults.Clear();
CurrentDirectoryResults.AddRange(sortedFolders);
CurrentDirectoryResults.AddRange(sortedContacts);
}
}
}

View File

@@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using PepperDash.Core;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents a CodecScheduleAwareness
/// </summary>
public class CodecScheduleAwareness
{
List<Meeting> _meetings;
/// <summary>
/// Event that is raised when a meeting event changes
/// </summary>
public event EventHandler<MeetingEventArgs> MeetingEventChange;
/// <summary>
/// Event that is raised when the meetings list has changed
/// </summary>
public event EventHandler<EventArgs> MeetingsListHasChanged;
private int _meetingWarningMinutes = 5;
//private Meeting _previousChangedMeeting;
//private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown;
/// <summary>
/// Gets or sets the number of minutes before a meeting to issue a warning
/// </summary>
public int MeetingWarningMinutes
{
get { return _meetingWarningMinutes; }
set { _meetingWarningMinutes = value; }
}
/// <summary>
/// Setter triggers MeetingsListHasChanged event
/// </summary>
public List<Meeting> Meetings
{
get
{
return _meetings;
}
set
{
_meetings = value;
MeetingsListHasChanged?.Invoke(this, new EventArgs());
}
}
private readonly CTimer _scheduleChecker;
/// <summary>
/// Initializes a new instance of the CodecScheduleAwareness class with default poll time
/// </summary>
public CodecScheduleAwareness()
{
Meetings = new List<Meeting>();
_scheduleChecker = new CTimer(CheckSchedule, null, 1000, 1000);
}
/// <summary>
/// Initializes a new instance of the CodecScheduleAwareness class with specified poll time
/// </summary>
/// <param name="pollTime">The poll time in milliseconds for checking schedule changes</param>
public CodecScheduleAwareness(long pollTime)
{
Meetings = new List<Meeting>();
_scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime);
}
/// <summary>
/// Helper method to fire MeetingEventChange. Should only fire once for each changeType on each meeting
/// </summary>
/// <param name="changeType"></param>
/// <param name="meeting"></param>
private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting)
{
Debug.LogMessage(LogEventLevel.Verbose, "*****************OnMeetingChange. id: {0} changeType: {1}**********************", meeting.Id, changeType);
if (changeType != (changeType & meeting.NotifiedChangeTypes))
{
// Add this change type to the NotifiedChangeTypes
meeting.NotifiedChangeTypes |= changeType;
MeetingEventChange?.Invoke(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
}
else
{
Debug.LogMessage(LogEventLevel.Verbose, "Meeting: {0} already notified of changeType: {1}", meeting.Id, changeType);
}
}
/// <summary>
/// Checks the schedule to see if any MeetingEventChange updates should be fired
/// </summary>
/// <param name="o"></param>
private void CheckSchedule(object o)
{
// Iterate the meeting list and check if any meeting need to do anything
const double meetingTimeEpsilon = 0.05;
foreach (var m in Meetings)
{
var changeType = eMeetingEventChangeType.Unknown;
if (eMeetingEventChangeType.MeetingStartWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStartWarning) && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start
{
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds);
changeType = eMeetingEventChangeType.MeetingStartWarning;
}
else if (eMeetingEventChangeType.MeetingStart != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStart) && Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
{
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStart");
changeType = eMeetingEventChangeType.MeetingStart;
}
else if (eMeetingEventChangeType.MeetingEndWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEndWarning) && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end
{
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEndWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingEnd.TotalMinutes, m.TimeToMeetingEnd.Seconds);
changeType = eMeetingEventChangeType.MeetingEndWarning;
}
else if (eMeetingEventChangeType.MeetingEnd != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEnd) && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
{
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEnd");
changeType = eMeetingEventChangeType.MeetingEnd;
}
if (changeType != eMeetingEventChangeType.Unknown)
{
OnMeetingChange(changeType, m);
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents a ContactMethod
/// </summary>
public class ContactMethod
{
/// <summary>
/// Gets or sets the ContactMethodId
/// </summary>
[JsonProperty("contactMethodId")]
public string ContactMethodId { get; set; }
/// <summary>
/// Gets or sets the Number
/// </summary>
[JsonProperty("number")]
public string Number { get; set; }
/// <summary>
/// Gets or sets the Device
/// </summary>
[JsonProperty("device")]
[JsonConverter(typeof(StringEnumConverter))]
public eContactMethodDevice Device { get; set; }
/// <summary>
/// Gets or sets the CallType
/// </summary>
[JsonProperty("callType")]
[JsonConverter(typeof(StringEnumConverter))]
public eContactMethodCallType CallType { get; set; }
}
}

View File

@@ -0,0 +1,39 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents a DirectoryContact
/// </summary>
public class DirectoryContact : DirectoryItem
{
/// <summary>
/// Gets or sets the ContactId
/// </summary>
[JsonProperty("contactId")]
public string ContactId { get; set; }
/// <summary>
/// Gets or sets the Title
/// </summary>
[JsonProperty("title")]
public string Title { get; set; }
/// <summary>
/// Gets or sets the ContactMethods
/// </summary>
[JsonProperty("contactMethods")]
public List<ContactMethod> ContactMethods { get; set; }
/// <summary>
/// Constructor for <see cref="DirectoryContact"/>
/// </summary>
public DirectoryContact()
{
ContactMethods = new List<ContactMethod>();
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents a DirectoryEventArgs
/// </summary>
public class DirectoryEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the Directory
/// </summary>
public CodecDirectory Directory { get; set; }
/// <summary>
/// Gets or sets the DirectoryIsOnRoot
/// </summary>
public bool DirectoryIsOnRoot { get; set; }
}
}

View File

@@ -0,0 +1,27 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents a DirectoryFolder
/// </summary>
public class DirectoryFolder : DirectoryItem
{
/// <summary>
/// Gets or sets the Contacts
/// </summary>
[JsonProperty("contacts")]
public List<DirectoryContact> Contacts { get; set; }
/// <summary>
/// Constructor for <see cref="DirectoryFolder"/>
/// </summary>
public DirectoryFolder()
{
Contacts = new List<DirectoryContact>();
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents a DirectoryItem
/// </summary>
public class DirectoryItem : ICloneable
{
/// <summary>
/// Clone method
/// </summary>
public object Clone()
{
return MemberwiseClone();
}
/// <summary>
/// Gets or sets the FolderId
/// </summary>
[JsonProperty("folderId")]
public string FolderId { get; set; }
/// <summary>
/// Gets or sets the Name
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets the ParentFolderId
/// </summary>
[JsonProperty("parentFolderId")]
public string ParentFolderId { get; set; }
}
}

View File

@@ -1,31 +1,65 @@
using Crestron.SimplSharpPro;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PepperDash.Essentials.Devices.Common.Codec
{
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Describes a cisco codec device that can allow configuration of cameras
/// </summary>
public interface ICiscoCodecCameraConfig
{
/// <summary>
/// Sets the assigned serial number for the specified camera
/// </summary>
/// <param name="cameraId">The camera identifier</param>
/// <param name="serialNumber">The serial number to assign</param>
void SetCameraAssignedSerialNumber(uint cameraId, string serialNumber);
/// <summary>
/// Sets the name for the camera on the specified video connector
/// </summary>
/// <param name="videoConnectorId">The video connector identifier</param>
/// <param name="name">The name to assign</param>
void SetCameraName(uint videoConnectorId, string name);
/// <summary>
/// Sets the input source type for the specified video connector
/// </summary>
/// <param name="videoConnectorId">The video connector identifier</param>
/// <param name="sourceType">The source type to set</param>
void SetInputSourceType(uint videoConnectorId, eCiscoCodecInputSourceType sourceType);
}
/// <summary>
/// Enumeration of Cisco codec input source types
/// </summary>
public enum eCiscoCodecInputSourceType
{
/// <summary>
/// PC source type
/// </summary>
PC,
/// <summary>
/// Camera source type
/// </summary>
camera,
/// <summary>
/// Document camera source type
/// </summary>
document_camera,
/// <summary>
/// Media player source type
/// </summary>
mediaplayer,
/// <summary>
/// Other source type
/// </summary>
other,
/// <summary>
/// Whiteboard source type
/// </summary>
whiteboard
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.Codec
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Defines the contract for IHasCallHold

View File

@@ -0,0 +1,14 @@
using System.Collections.Generic;
using PepperDash.Essentials.Devices.Common.Codec;
/// <summary>
/// Defines the contract for IHasDirectoryHistoryStack
/// </summary>
public interface IHasDirectoryHistoryStack : IHasDirectory
{
/// <summary>
/// Gets the DirectoryBrowseHistoryStack
/// </summary>
Stack<CodecDirectory> DirectoryBrowseHistoryStack { get; }
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Codec
{
@@ -34,6 +28,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
void ToggleDoNotDisturbMode();
}
/// <summary>
/// Defines the contract for devices that support Do Not Disturb mode with timeout functionality
/// </summary>
public interface IHasDoNotDisturbModeWithTimeout : IHasDoNotDisturbMode
{
/// <summary>

View File

@@ -1,25 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Defines the contract for IHasExternalSourceSwitching
/// </summary>
/// <summary>
/// Defines the contract for IHasExternalSourceSwitching
/// </summary>
public interface IHasExternalSourceSwitching
{
/// <summary>
/// Gets a value indicating whether the external source list is enabled
/// </summary>
bool ExternalSourceListEnabled { get; }
string ExternalSourceInputPort { get; }
/// <summary>
/// Gets the external source input port identifier
/// </summary>
string ExternalSourceInputPort { get; }
/// <summary>
/// Adds an external source to the available sources
/// </summary>
/// <param name="connectorId">The connector identifier</param>
/// <param name="key">The unique key for the source</param>
/// <param name="name">The display name for the source</param>
/// <param name="type">The type of external source</param>
void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type);
/// <summary>
/// Sets the state of the specified external source
/// </summary>
/// <param name="key">The unique key of the external source</param>
/// <param name="mode">The mode to set for the source</param>
void SetExternalSourceState(string key, eExternalSourceMode mode);
/// <summary>
/// Clears all external sources from the list
/// </summary>
void ClearExternalSources();
void SetSelectedSource(string key);
Action<string, string> RunRouteAction { set;}
/// <summary>
/// Sets the selected source by its key
/// </summary>
/// <param name="key">The unique key of the source to select</param>
void SetSelectedSource(string key);
/// <summary>
/// Sets the action to run when routing between sources
/// </summary>
Action<string, string> RunRouteAction { set; }
}
}

View File

@@ -0,0 +1,13 @@
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Defines the contract for IInvitableContact
/// </summary>
public interface IInvitableContact
{
/// <summary>
/// Gets a value indicating whether this contact is invitable
/// </summary>
bool IsInvitableContact { get; }
}
}

View File

@@ -0,0 +1,22 @@
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents an InvitableDirectoryContact
/// </summary>
public class InvitableDirectoryContact : DirectoryContact, IInvitableContact
{
/// <summary>
/// Gets a value indicating whether this contact is invitable
/// </summary>
[JsonProperty("isInvitableContact")]
public bool IsInvitableContact
{
get
{
return this is IInvitableContact;
}
}
}
}

View File

@@ -0,0 +1,182 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents a Meeting
/// </summary>
public class Meeting
{
/// <summary>
/// Minutes before the meeting to show warning
/// </summary>
[JsonProperty("minutesBeforeMeeting")]
public int MinutesBeforeMeeting;
/// <summary>
/// Gets or sets the meeting ID
/// </summary>
[JsonProperty("id")]
public string Id { get; set; }
/// <summary>
/// Gets or sets the meeting organizer
/// </summary>
[JsonProperty("organizer")]
public string Organizer { get; set; }
/// <summary>
/// Gets or sets the Title
/// </summary>
[JsonProperty("title")]
public string Title { get; set; }
/// <summary>
/// Gets or sets the Agenda
/// </summary>
[JsonProperty("agenda")]
public string Agenda { get; set; }
/// <summary>
/// Gets the meeting warning time span in minutes before the meeting starts
/// </summary>
[JsonProperty("meetingWarningMinutes")]
public TimeSpan MeetingWarningMinutes
{
get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); }
}
/// <summary>
/// Gets the time remaining until the meeting starts
/// </summary>
[JsonProperty("timeToMeetingStart")]
public TimeSpan TimeToMeetingStart
{
get
{
return StartTime - DateTime.Now;
}
}
/// <summary>
/// Gets the time remaining until the meeting ends
/// </summary>
[JsonProperty("timeToMeetingEnd")]
public TimeSpan TimeToMeetingEnd
{
get
{
return EndTime - DateTime.Now;
}
}
/// <summary>
/// Gets or sets the StartTime
/// </summary>
[JsonProperty("startTime")]
public DateTime StartTime { get; set; }
/// <summary>
/// Gets or sets the EndTime
/// </summary>
[JsonProperty("endTime")]
public DateTime EndTime { get; set; }
/// <summary>
/// Gets the duration of the meeting
/// </summary>
[JsonProperty("duration")]
public TimeSpan Duration
{
get
{
return EndTime - StartTime;
}
}
/// <summary>
/// Gets or sets the Privacy
/// </summary>
[JsonProperty("privacy")]
public eMeetingPrivacy Privacy { get; set; }
/// <summary>
/// Gets a value indicating whether the meeting can be joined
/// </summary>
[JsonProperty("joinable")]
public bool Joinable
{
get
{
var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now
&& DateTime.Now <= EndTime.AddSeconds(-_joinableCooldownSeconds);
//Debug.LogMessage(LogEventLevel.Verbose, "Meeting Id: {0} joinable: {1}", Id, joinable);
return joinable;
}
}
/// <summary>
/// Gets or sets the Dialable
/// </summary>
[JsonProperty("dialable")]
public bool Dialable { get; set; }
//public string ConferenceNumberToDial { get; set; }
/// <summary>
/// Gets or sets the ConferencePassword
/// </summary>
[JsonProperty("conferencePassword")]
public string ConferencePassword { get; set; }
/// <summary>
/// Gets or sets the IsOneButtonToPushMeeting
/// </summary>
[JsonProperty("isOneButtonToPushMeeting")]
public bool IsOneButtonToPushMeeting { get; set; }
/// <summary>
/// Gets or sets the Calls
/// </summary>
[JsonProperty("calls")]
public List<Call> Calls { get; private set; }
/// <summary>
/// Tracks the change types that have already been notified for
/// Gets or sets the NotifiedChangeTypes
/// </summary>
[JsonIgnore]
public eMeetingEventChangeType NotifiedChangeTypes { get; set; }
[JsonIgnore] private readonly int _joinableCooldownSeconds;
/// <summary>
/// Constructor for Meeting <see cref="Meeting"/>
/// </summary>
public Meeting()
{
Calls = new List<Call>();
_joinableCooldownSeconds = 300;
}
/// <summary>
/// Constructor for Meeting <see cref="Meeting"/>
/// </summary>
/// <param name="joinableCooldownSeconds">Number of seconds after meeting start when it is no longer joinable</param>
public Meeting(int joinableCooldownSeconds)
{
Calls = new List<Call>();
_joinableCooldownSeconds = joinableCooldownSeconds;
}
#region Overrides of Object
/// <summary>
/// ToString method
/// </summary>
/// <inheritdoc />
public override string ToString()
{
return string.Format("{0}:{1}: {2}-{3}", Title, Agenda, StartTime, EndTime);
}
#endregion
}
}

View File

@@ -0,0 +1,22 @@
using System;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents a MeetingEventArgs
/// </summary>
public class MeetingEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the ChangeType
/// </summary>
public eMeetingEventChangeType ChangeType { get; set; }
/// <summary>
/// Gets or sets the Meeting
/// </summary>
public Meeting Meeting { get; set; }
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.Codec
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
@@ -12,7 +6,20 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public enum eCodecCallDirection
{
Unknown = 0, Incoming, Outgoing
/// <summary>
/// Unknown call direction
/// </summary>
Unknown = 0,
/// <summary>
/// Incoming call direction
/// </summary>
Incoming,
/// <summary>
/// Outgoing call direction
/// </summary>
Outgoing
}
/// <summary>

View File

@@ -1,27 +1,68 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.Codec
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Enumeration of eCodecCallStatus values
/// </summary>
public enum eCodecCallStatus
{
/// <summary>
/// Unknown call status
/// </summary>
Unknown = 0,
Connected,
Connecting,
Dialing,
/// <summary>
/// Call is connected
/// </summary>
Connected,
/// <summary>
/// Call is connecting
/// </summary>
Connecting,
/// <summary>
/// Call is dialing
/// </summary>
Dialing,
/// <summary>
/// Call is disconnected
/// </summary>
Disconnected,
Disconnecting,
EarlyMedia,
/// <summary>
/// Call is disconnecting
/// </summary>
Disconnecting,
/// <summary>
/// Early media is being sent/received
/// </summary>
EarlyMedia,
/// <summary>
/// Call is idle
/// </summary>
Idle,
OnHold,
Ringing,
Preserved,
/// <summary>
/// Call is on hold
/// </summary>
OnHold,
/// <summary>
/// Call is ringing
/// </summary>
Ringing,
/// <summary>
/// Call is preserved
/// </summary>
Preserved,
/// <summary>
/// Call is remote preserved
/// </summary>
RemotePreserved,
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.Codec
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
@@ -12,10 +6,29 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public enum eCodecCallType
{
Unknown = 0,
Audio,
Video,
AudioCanEscalate,
/// <summary>
/// Unknown call type
/// </summary>
Unknown = 0,
/// <summary>
/// Audio-only call type
/// </summary>
Audio,
/// <summary>
/// Video call type
/// </summary>
Video,
/// <summary>
/// Audio call that can be escalated to video
/// </summary>
AudioCanEscalate,
/// <summary>
/// Forward all call type
/// </summary>
ForwardAllCall
}

View File

@@ -0,0 +1,21 @@
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Enumeration of eContactMethodCallType values
/// </summary>
public enum eContactMethodCallType
{
/// <summary>
/// Unknown call type
/// </summary>
Unknown = 0,
/// <summary>
/// Audio call type
/// </summary>
Audio,
/// <summary>
/// Video call type
/// </summary>
Video
}
}

View File

@@ -0,0 +1,29 @@
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Enumeration of eContactMethodDevice values
/// </summary>
public enum eContactMethodDevice
{
/// <summary>
/// Unknown contact method
/// </summary>
Unknown = 0,
/// <summary>
/// Mobile contact method
/// </summary>
Mobile,
/// <summary>
/// Other contact method
/// </summary>
Other,
/// <summary>
/// Telephone contact method
/// </summary>
Telephone,
/// <summary>
/// Video contact method
/// </summary>
Video
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Enumeration of eMeetingEventChangeType values
/// </summary>
[Flags]
public enum eMeetingEventChangeType
{
/// <summary>
/// Unknown change type
/// </summary>
Unknown = 0,
/// <summary>
/// Meeting start warning
/// </summary>
MeetingStartWarning = 1,
/// <summary>
/// Meeting start
/// </summary>
MeetingStart = 2,
/// <summary>
/// Meeting end warning
/// </summary>
MeetingEndWarning = 4,
/// <summary>
/// Meeting end
/// </summary>
MeetingEnd = 8
}
}

View File

@@ -1,18 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.Codec
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Enumeration of eMeetingPrivacy values
/// </summary>
public enum eMeetingPrivacy
{
/// <summary>
/// Unknown meeting privacy level
/// </summary>
Unknown = 0,
/// <summary>
/// Public meeting
/// </summary>
Public,
/// <summary>
/// Private meeting
/// </summary>
Private
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Codec
{

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using System.Collections.Generic;
namespace PepperDash.Essentials.Devices.Common.Codec
{
@@ -11,6 +7,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public interface IHasCallFavorites
{
/// <summary>
/// Gets the call favorites for this device
/// </summary>
CodecCallFavorites CallFavorites { get; }
}
@@ -24,6 +23,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public List<CodecActiveCallItem> Favorites { get; set; }
/// <summary>
/// Initializes a new instance of the CodecCallFavorites class
/// </summary>
public CodecCallFavorites()
{
Favorites = new List<CodecActiveCallItem>();

View File

@@ -2,10 +2,9 @@
using System;
using System.Collections.Generic;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials.Devices.Common.Codec
{
@@ -15,8 +14,15 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public interface IHasCallHistory
{
/// <summary>
/// Gets the call history for this device
/// </summary>
CodecCallHistory CallHistory { get; }
/// <summary>
/// Removes the specified call history entry
/// </summary>
/// <param name="entry">The call history entry to remove</param>
void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry);
}
@@ -25,9 +31,24 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public enum eCodecOccurrenceType
{
/// <summary>
/// Unknown occurrence type
/// </summary>
Unknown = 0,
/// <summary>
/// Call was placed (outgoing)
/// </summary>
Placed = 1,
/// <summary>
/// Call was received (incoming)
/// </summary>
Received = 2,
/// <summary>
/// Call received no answer
/// </summary>
NoAnswer = 3,
}
@@ -36,6 +57,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public class CodecCallHistory
{
/// <summary>
/// Event that is raised when the recent calls list has changed
/// </summary>
public event EventHandler<EventArgs> RecentCallsListHasChanged;
/// <summary>
@@ -48,6 +72,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
CallHistoryEntry ListEmptyEntry;
/// <summary>
/// Initializes a new instance of the CodecCallHistory class
/// </summary>
public CodecCallHistory()
{
ListEmptyEntry = new CallHistoryEntry() { Name = "No Recent Calls" };
@@ -80,15 +107,22 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public class CallHistoryEntry : CodecActiveCallItem
{
[JsonConverter(typeof(IsoDateTimeConverter))]
[JsonProperty("startTime")]
/// <summary>
/// Gets or sets the StartTime
/// </summary>
[JsonConverter(typeof(IsoDateTimeConverter))]
[JsonProperty("startTime")]
public DateTime StartTime { get; set; }
/// <summary>
/// Gets or sets the occurrence type for this call history entry
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty("occurrenceType")]
public eCodecOccurrenceType OccurrenceType { get; set; }
/// <summary>
/// Gets or sets the occurrence history identifier
/// </summary>
[JsonProperty("occurrenceHistoryId")]
public string OccurrenceHistoryId { get; set; }
}
@@ -119,7 +153,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
}
// Check if list is empty and if so, add an item to display No Recent Calls
if(genericEntries.Count == 0)
if (genericEntries.Count == 0)
genericEntries.Add(ListEmptyEntry);
RecentCalls = genericEntries;

View File

@@ -1,11 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Codec
@@ -15,12 +8,29 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public interface IHasContentSharing
{
/// <summary>
/// Gets feedback indicating whether content sharing is currently active
/// </summary>
BoolFeedback SharingContentIsOnFeedback { get; }
/// <summary>
/// Gets feedback about the current sharing source
/// </summary>
StringFeedback SharingSourceFeedback { get; }
/// <summary>
/// Gets a value indicating whether content should be automatically shared while in a call
/// </summary>
bool AutoShareContentWhileInCall { get; }
/// <summary>
/// Starts content sharing
/// </summary>
void StartSharing();
/// <summary>
/// Stops content sharing
/// </summary>
void StopSharing();
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Codec
{
@@ -15,15 +9,49 @@ namespace PepperDash.Essentials.Devices.Common.Codec
{
// Add requirements for Dialer functionality
/// <summary>
/// Event that is raised when call status changes
/// </summary>
event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
/// <summary>
/// Dials the specified number
/// </summary>
/// <param name="number">The number to dial</param>
void Dial(string number);
/// <summary>
/// Ends the specified active call
/// </summary>
/// <param name="activeCall">The active call to end</param>
void EndCall(CodecActiveCallItem activeCall);
/// <summary>
/// Ends all active calls
/// </summary>
void EndAllCalls();
/// <summary>
/// Accepts the specified incoming call
/// </summary>
/// <param name="item">The call item to accept</param>
void AcceptCall(CodecActiveCallItem item);
/// <summary>
/// Rejects the specified incoming call
/// </summary>
/// <param name="item">The call item to reject</param>
void RejectCall(CodecActiveCallItem item);
/// <summary>
/// Sends DTMF digits during a call
/// </summary>
/// <param name="digit">The DTMF digit(s) to send</param>
void SendDtmf(string digit);
/// <summary>
/// Gets a value indicating whether the device is currently in a call
/// </summary>
bool IsInCall { get; }
}

View File

@@ -1,319 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Defines the API for codecs with a directory
/// </summary>
/// <summary>
/// Defines the API for codecs with a directory
/// </summary>
public interface IHasDirectory
{
/// <summary>
/// Event that fires when a directory result is returned from the codec
/// </summary>
event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
/// <summary>
/// Gets the DirectoryRoot
/// </summary>
CodecDirectory DirectoryRoot { get; }
/// <summary>
/// Gets the CurrentDirectoryResult
/// </summary>
CodecDirectory CurrentDirectoryResult { get; }
/// <summary>
/// Gets the PhonebookSyncState
/// </summary>
CodecPhonebookSyncState PhonebookSyncState { get; }
/// <summary>
/// Method to initiate a search of the directory on the server
/// </summary>
void SearchDirectory(string searchString);
/// <summary>
/// Method to get the contents of a specific folder in the directory on the server
/// </summary>
void GetDirectoryFolderContents(string folderId);
/// <summary>
/// Method to set the current directory to the root folder
/// </summary>
void SetCurrentDirectoryToRoot();
/// <summary>
/// Method to get the contents of the parent folder in the directory on the server
/// </summary>
void GetDirectoryParentFolderContents();
/// <summary>
/// Gets the CurrentDirectoryResultIsNotDirectoryRoot
/// </summary>
BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; }
}
/// <summary>
/// Defines the contract for IHasDirectoryHistoryStack
/// </summary>
public interface IHasDirectoryHistoryStack : IHasDirectory
{
Stack<CodecDirectory> DirectoryBrowseHistoryStack { get; }
}
/// <summary>
/// Represents a DirectoryEventArgs
/// </summary>
public class DirectoryEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the Directory
/// </summary>
public CodecDirectory Directory { get; set; }
/// <summary>
/// Gets or sets the DirectoryIsOnRoot
/// </summary>
public bool DirectoryIsOnRoot { get; set; }
}
/// <summary>
/// Represents a codec directory
/// </summary>
public class CodecDirectory
{
/// <summary>
/// Represents the contents of the directory
/// We don't want to serialize this for messages to MobileControl. MC can combine Contacts and Folders to get the same data
/// </summary>
[JsonIgnore]
public List<DirectoryItem> CurrentDirectoryResults { get; private set; }
[JsonProperty("contacts")]
public List<DirectoryItem> Contacts
{
get
{
return CurrentDirectoryResults.OfType<DirectoryContact>().Cast<DirectoryItem>().ToList();
}
}
[JsonProperty("folders")]
public List<DirectoryItem> Folders
{
get
{
return CurrentDirectoryResults.OfType<DirectoryFolder>().Cast<DirectoryItem>().ToList();
}
}
/// <summary>
/// Used to store the ID of the current folder for CurrentDirectoryResults
/// </summary>
[JsonProperty("resultsFolderId")]
/// <summary>
/// Gets or sets the ResultsFolderId
/// </summary>
public string ResultsFolderId { get; set; }
public CodecDirectory()
{
CurrentDirectoryResults = new List<DirectoryItem>();
}
/// <summary>
/// Adds folders to the directory
/// </summary>
/// <param name="folders"></param>
/// <summary>
/// AddFoldersToDirectory method
/// </summary>
public void AddFoldersToDirectory(List<DirectoryItem> folders)
{
if(folders != null)
CurrentDirectoryResults.AddRange(folders);
SortDirectory();
}
/// <summary>
/// Adds contacts to the directory
/// </summary>
/// <param name="contacts"></param>
/// <summary>
/// AddContactsToDirectory method
/// </summary>
public void AddContactsToDirectory(List<DirectoryItem> contacts)
{
if(contacts != null)
CurrentDirectoryResults.AddRange(contacts);
SortDirectory();
}
/// <summary>
/// Filters the CurrentDirectoryResults by the predicate
/// </summary>
/// <param name="predicate"></param>
/// <summary>
/// FilterContacts method
/// </summary>
public void FilterContacts(Func<DirectoryItem, bool> predicate)
{
CurrentDirectoryResults = CurrentDirectoryResults.Where(predicate).ToList();
}
/// <summary>
/// Sorts the DirectoryResults list to display all folders alphabetically, then all contacts alphabetically
/// </summary>
private void SortDirectory()
{
var sortedFolders = new List<DirectoryItem>();
sortedFolders.AddRange(CurrentDirectoryResults.Where(f => f is DirectoryFolder));
sortedFolders.OrderBy(f => f.Name);
var sortedContacts = new List<DirectoryItem>();
sortedContacts.AddRange(CurrentDirectoryResults.Where(c => c is DirectoryContact));
sortedFolders.OrderBy(c => c.Name);
CurrentDirectoryResults.Clear();
CurrentDirectoryResults.AddRange(sortedFolders);
CurrentDirectoryResults.AddRange(sortedContacts);
}
}
/// <summary>
/// Defines the contract for IInvitableContact
/// </summary>
public interface IInvitableContact
{
bool IsInvitableContact { get; }
}
public class InvitableDirectoryContact : DirectoryContact, IInvitableContact
{
[JsonProperty("isInvitableContact")]
public bool IsInvitableContact
{
get
{
return this is IInvitableContact;
}
}
}
/// <summary>
/// Represents a DirectoryItem
/// </summary>
public class DirectoryItem : ICloneable
{
/// <summary>
/// Clone method
/// </summary>
public object Clone()
{
return this.MemberwiseClone();
}
[JsonProperty("folderId")]
public string FolderId { get; set; }
[JsonProperty("name")]
/// <summary>
/// Gets or sets the Name
/// </summary>
public string Name { get; set; }
[JsonProperty("parentFolderId")]
/// <summary>
/// Gets or sets the ParentFolderId
/// </summary>
public string ParentFolderId { get; set; }
}
/// <summary>
/// Represents a DirectoryFolder
/// </summary>
public class DirectoryFolder : DirectoryItem
{
[JsonProperty("contacts")]
/// <summary>
/// Gets or sets the Contacts
/// </summary>
public List<DirectoryContact> Contacts { get; set; }
public DirectoryFolder()
{
Contacts = new List<DirectoryContact>();
}
}
/// <summary>
/// Represents a DirectoryContact
/// </summary>
public class DirectoryContact : DirectoryItem
{
[JsonProperty("contactId")]
/// <summary>
/// Gets or sets the ContactId
/// </summary>
public string ContactId { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("contactMethods")]
public List<ContactMethod> ContactMethods { get; set; }
public DirectoryContact()
{
ContactMethods = new List<ContactMethod>();
}
}
/// <summary>
/// Represents a ContactMethod
/// </summary>
public class ContactMethod
{
[JsonProperty("contactMethodId")]
/// <summary>
/// Gets or sets the ContactMethodId
/// </summary>
public string ContactMethodId { get; set; }
[JsonProperty("number")]
public string Number { get; set; }
[JsonProperty("device")]
[JsonConverter(typeof(StringEnumConverter))]
/// <summary>
/// Gets or sets the Device
/// </summary>
public eContactMethodDevice Device { get; set; }
[JsonProperty("callType")]
[JsonConverter(typeof(StringEnumConverter))]
/// <summary>
/// Gets or sets the CallType
/// </summary>
public eContactMethodCallType CallType { get; set; }
}
/// <summary>
/// Enumeration of eContactMethodDevice values
/// </summary>
public enum eContactMethodDevice
{
Unknown = 0,
Mobile,
Other,
Telephone,
Video
}
/// <summary>
/// Enumeration of eContactMethodCallType values
/// </summary>
public enum eContactMethodCallType
{
Unknown = 0,
Audio,
Video
}
}

View File

@@ -1,339 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using Newtonsoft.Json;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Codec
namespace PepperDash.Essentials.Devices.Common.Codec
{
[Flags]
/// <summary>
/// Enumeration of eMeetingEventChangeType values
/// </summary>
public enum eMeetingEventChangeType
{
Unknown = 0,
MeetingStartWarning = 1,
MeetingStart = 2,
MeetingEndWarning = 4,
MeetingEnd = 8
}
/// <summary>
/// Defines the contract for IHasScheduleAwareness
/// </summary>
public interface IHasScheduleAwareness
{
/// <summary>
/// Gets the CodecScheduleAwareness instance
/// </summary>
CodecScheduleAwareness CodecSchedule { get; }
/// <summary>
/// Method to initiate getting the schedule from the server
/// </summary>
void GetSchedule();
}
/// <summary>
/// Represents a CodecScheduleAwareness
/// </summary>
public class CodecScheduleAwareness
{
List<Meeting> _meetings;
public event EventHandler<MeetingEventArgs> MeetingEventChange;
public event EventHandler<EventArgs> MeetingsListHasChanged;
private int _meetingWarningMinutes = 5;
//private Meeting _previousChangedMeeting;
//private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown;
public int MeetingWarningMinutes
{
get { return _meetingWarningMinutes; }
set { _meetingWarningMinutes = value; }
}
/// <summary>
/// Setter triggers MeetingsListHasChanged event
/// </summary>
public List<Meeting> Meetings
{
get
{
return _meetings;
}
set
{
_meetings = value;
MeetingsListHasChanged?.Invoke(this, new EventArgs());
}
}
private readonly CTimer _scheduleChecker;
public CodecScheduleAwareness()
{
Meetings = new List<Meeting>();
_scheduleChecker = new CTimer(CheckSchedule, null, 1000, 1000);
}
public CodecScheduleAwareness(long pollTime)
{
Meetings = new List<Meeting>();
_scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime);
}
/// <summary>
/// Helper method to fire MeetingEventChange. Should only fire once for each changeType on each meeting
/// </summary>
/// <param name="changeType"></param>
/// <param name="meeting"></param>
private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting)
{
Debug.LogMessage(LogEventLevel.Verbose, "*****************OnMeetingChange. id: {0} changeType: {1}**********************", meeting.Id, changeType);
if (changeType != (changeType & meeting.NotifiedChangeTypes))
{
// Add this change type to the NotifiedChangeTypes
meeting.NotifiedChangeTypes |= changeType;
MeetingEventChange?.Invoke(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
}
else
{
Debug.LogMessage(LogEventLevel.Verbose, "Meeting: {0} already notified of changeType: {1}", meeting.Id, changeType);
}
}
/// <summary>
/// Checks the schedule to see if any MeetingEventChange updates should be fired
/// </summary>
/// <param name="o"></param>
private void CheckSchedule(object o)
{
// Iterate the meeting list and check if any meeting need to do anything
const double meetingTimeEpsilon = 0.05;
foreach (var m in Meetings)
{
var changeType = eMeetingEventChangeType.Unknown;
if (eMeetingEventChangeType.MeetingStartWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStartWarning) && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start
{
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds);
changeType = eMeetingEventChangeType.MeetingStartWarning;
}
else if (eMeetingEventChangeType.MeetingStart != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStart) && Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
{
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStart");
changeType = eMeetingEventChangeType.MeetingStart;
}
else if (eMeetingEventChangeType.MeetingEndWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEndWarning) && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end
{
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEndWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingEnd.TotalMinutes, m.TimeToMeetingEnd.Seconds);
changeType = eMeetingEventChangeType.MeetingEndWarning;
}
else if (eMeetingEventChangeType.MeetingEnd != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEnd) && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
{
Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEnd");
changeType = eMeetingEventChangeType.MeetingEnd;
}
if (changeType != eMeetingEventChangeType.Unknown)
{
OnMeetingChange(changeType, m);
}
}
}
}
/// <summary>
/// Represents a Meeting
/// </summary>
public class Meeting
{
[JsonProperty("minutesBeforeMeeting")]
public int MinutesBeforeMeeting;
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("organizer")]
public string Organizer { get; set; }
[JsonProperty("title")]
/// <summary>
/// Gets or sets the Title
/// </summary>
public string Title { get; set; }
[JsonProperty("agenda")]
/// <summary>
/// Gets or sets the Agenda
/// </summary>
public string Agenda { get; set; }
[JsonProperty("meetingWarningMinutes")]
public TimeSpan MeetingWarningMinutes
{
get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); }
}
[JsonProperty("timeToMeetingStart")]
public TimeSpan TimeToMeetingStart
{
get
{
return StartTime - DateTime.Now;
}
}
[JsonProperty("timeToMeetingEnd")]
public TimeSpan TimeToMeetingEnd
{
get
{
return EndTime - DateTime.Now;
}
}
[JsonProperty("startTime")]
/// <summary>
/// Gets or sets the StartTime
/// </summary>
public DateTime StartTime { get; set; }
[JsonProperty("endTime")]
/// <summary>
/// Gets or sets the EndTime
/// </summary>
public DateTime EndTime { get; set; }
[JsonProperty("duration")]
public TimeSpan Duration
{
get
{
return EndTime - StartTime;
}
}
[JsonProperty("privacy")]
/// <summary>
/// Gets or sets the Privacy
/// </summary>
public eMeetingPrivacy Privacy { get; set; }
[JsonProperty("joinable")]
public bool Joinable
{
get
{
var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now
&& DateTime.Now <= EndTime.AddSeconds(-_joinableCooldownSeconds);
//Debug.LogMessage(LogEventLevel.Verbose, "Meeting Id: {0} joinable: {1}", Id, joinable);
return joinable;
}
}
[JsonProperty("dialable")]
/// <summary>
/// Gets or sets the Dialable
/// </summary>
public bool Dialable { get; set; }
//public string ConferenceNumberToDial { get; set; }
[JsonProperty("conferencePassword")]
/// <summary>
/// Gets or sets the ConferencePassword
/// </summary>
public string ConferencePassword { get; set; }
[JsonProperty("isOneButtonToPushMeeting")]
/// <summary>
/// Gets or sets the IsOneButtonToPushMeeting
/// </summary>
public bool IsOneButtonToPushMeeting { get; set; }
[JsonProperty("calls")]
/// <summary>
/// Gets or sets the Calls
/// </summary>
public List<Call> Calls { get; private set; }
/// <summary>
/// Tracks the change types that have already been notified for
/// </summary>
[JsonIgnore]
/// <summary>
/// Gets or sets the NotifiedChangeTypes
/// </summary>
public eMeetingEventChangeType NotifiedChangeTypes { get; set; }
[JsonIgnore] private readonly int _joinableCooldownSeconds;
public Meeting()
{
Calls = new List<Call>();
_joinableCooldownSeconds = 300;
}
public Meeting(int joinableCooldownSeconds)
{
Calls = new List<Call>();
_joinableCooldownSeconds = joinableCooldownSeconds;
}
#region Overrides of Object
/// <summary>
/// ToString method
/// </summary>
/// <inheritdoc />
public override string ToString()
{
return String.Format("{0}:{1}: {2}-{3}", Title, Agenda, StartTime, EndTime);
}
#endregion
}
/// <summary>
/// Represents a Call
/// </summary>
public class Call
{
/// <summary>
/// Gets or sets the Number
/// </summary>
public string Number { get; set; }
/// <summary>
/// Gets or sets the Protocol
/// </summary>
public string Protocol { get; set; }
/// <summary>
/// Gets or sets the CallRate
/// </summary>
public string CallRate { get; set; }
/// <summary>
/// Gets or sets the CallType
/// </summary>
public string CallType { get; set; }
}
/// <summary>
/// Represents a MeetingEventArgs
/// </summary>
public class MeetingEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the ChangeType
/// </summary>
public eMeetingEventChangeType ChangeType { get; set; }
/// <summary>
/// Gets or sets the Meeting
/// </summary>
public Meeting Meeting { get; set; }
}
}

View File

@@ -1,61 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials.Devices.Common.DSP
{
public abstract class DspBase : EssentialsDevice, ILevelControls
{
public Dictionary<string,IBasicVolumeWithFeedback> LevelControlPoints { get; private set; }
/// <summary>
/// Base class for DSP devices
/// </summary>
public abstract class DspBase : EssentialsDevice, ILevelControls
{
/// <summary>
/// Gets the collection of level control points
/// </summary>
public Dictionary<string, IBasicVolumeWithFeedback> LevelControlPoints { get; private set; }
/// <summary>
/// Gets the collection of dialer control points
/// </summary>
public Dictionary<string, DspControlPoint> DialerControlPoints { get; private set; }
/// <summary>
/// Gets the collection of switcher control points
/// </summary>
public Dictionary<string, DspControlPoint> SwitcherControlPoints { get; private set; }
public DspBase(string key, string name) :
base(key, name)
{
/// <summary>
/// Initializes a new instance of the DspBase class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
public DspBase(string key, string name) :
base(key, name)
{
LevelControlPoints = new Dictionary<string, IBasicVolumeWithFeedback>();
DialerControlPoints = new Dictionary<string, DspControlPoint>();
SwitcherControlPoints = new Dictionary<string, DspControlPoint>();
}
LevelControlPoints = new Dictionary<string, IBasicVolumeWithFeedback>();
DialerControlPoints = new Dictionary<string, DspControlPoint>();
SwitcherControlPoints = new Dictionary<string, DspControlPoint>();
}
// in audio call feedback
// in audio call feedback
// VOIP
// Phone dialer
// VOIP
// Phone dialer
}
}
// Fusion
// Privacy state
// Online state
// level/mutes ?
// AC Log call stats
// Typical presets:
// call default preset to restore levels and mutes
// Fusion
// Privacy state
// Online state
// level/mutes ?
public abstract class DspControlPoint :IKeyed
{
// AC Log call stats
// Typical presets:
// call default preset to restore levels and mutes
/// <summary>
/// Base class for DSP control points
/// </summary>
public abstract class DspControlPoint : IKeyed
{
/// <summary>
/// Gets or sets the Key
/// </summary>
public string Key { get; }
/// <summary>
/// Initializes a new instance of the DspControlPoint class
/// </summary>
/// <param name="key">The control point key</param>
protected DspControlPoint(string key) => Key = key;
}
}
public abstract class DspLevelControlPoint :DspControlPoint, IBasicVolumeWithFeedback
/// <summary>
/// Base class for DSP level control points with volume and mute functionality
/// </summary>
public abstract class DspLevelControlPoint : DspControlPoint, IBasicVolumeWithFeedback
{
/// <summary>
/// Gets or sets the MuteFeedback
@@ -66,30 +89,63 @@ namespace PepperDash.Essentials.Devices.Common.DSP
/// </summary>
public IntFeedback VolumeLevelFeedback { get; }
/// <summary>
/// Initializes a new instance of the DspLevelControlPoint class
/// </summary>
/// <param name="key">The control point key</param>
/// <param name="muteFeedbackFunc">Function to get mute status</param>
/// <param name="volumeLevelFeedbackFunc">Function to get volume level</param>
protected DspLevelControlPoint(string key, Func<bool> muteFeedbackFunc, Func<int> volumeLevelFeedbackFunc) : base(key)
{
MuteFeedback = new BoolFeedback(muteFeedbackFunc);
VolumeLevelFeedback = new IntFeedback(volumeLevelFeedbackFunc);
MuteFeedback = new BoolFeedback("mute", muteFeedbackFunc);
VolumeLevelFeedback = new IntFeedback("volume", volumeLevelFeedbackFunc);
}
/// <summary>
/// Turns mute off
/// </summary>
public abstract void MuteOff();
/// <summary>
/// Turns mute on
/// </summary>
public abstract void MuteOn();
/// <summary>
/// Toggles mute state
/// </summary>
public abstract void MuteToggle();
/// <summary>
/// Sets the volume level
/// </summary>
/// <param name="level">The volume level to set</param>
public abstract void SetVolume(ushort level);
/// <summary>
/// Decreases volume
/// </summary>
/// <param name="pressRelease">True when pressed, false when released</param>
public abstract void VolumeDown(bool pressRelease);
/// <summary>
/// Increases volume
/// </summary>
/// <param name="pressRelease">True when pressed, false when released</param>
public abstract void VolumeUp(bool pressRelease);
}
public abstract class DspDialerBase:DspControlPoint
{
/// <summary>
/// Base class for DSP dialer control points
/// </summary>
public abstract class DspDialerBase : DspControlPoint
{
/// <summary>
/// Initializes a new instance of the DspDialerBase class
/// </summary>
/// <param name="key">The dialer control point key</param>
protected DspDialerBase(string key) : base(key) { }
}
}
// Main program
// VTC
// ATC
// Mics, unusual
// Main program
// VTC
// ATC
// Mics, unusual
}

View File

@@ -14,7 +14,9 @@ namespace PepperDash.Essentials.Devices.Common
/// </summary>
public class DeviceFactory
{
/// <summary>
/// Initializes a new instance of the DeviceFactory class
/// </summary>
public DeviceFactory()
{
var assy = Assembly.GetExecutingAssembly();

View File

@@ -11,37 +11,53 @@ using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Displays
{
/// <summary>
/// Represents a BasicIrDisplay
/// </summary>
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced
/// <summary>
/// Represents a BasicIrDisplay
/// </summary>
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced
{
/// <summary>
/// Gets or sets the IrPort
/// </summary>
/// <summary>
/// Gets or sets the IrPort
/// </summary>
public IrOutputPortController IrPort { get; private set; }
/// <summary>
/// Gets or sets the IrPulseTime
/// </summary>
/// <summary>
/// Gets or sets the IrPulseTime
/// </summary>
public ushort IrPulseTime { get; set; }
protected Func<bool> PowerIsOnFeedbackFunc
{
get { return () => _PowerIsOn; }
}
/// <summary>
/// Gets the power is on feedback function
/// </summary>
protected Func<bool> PowerIsOnFeedbackFunc
{
get { return () => _PowerIsOn; }
}
/// <summary>
/// Gets the is cooling down feedback function
/// </summary>
protected override Func<bool> IsCoolingDownFeedbackFunc
{
get { return () => _IsCoolingDown; }
}
/// <summary>
/// Gets the is warming up feedback function
/// </summary>
protected override Func<bool> IsWarmingUpFeedbackFunc
{
get { return () => _IsWarmingUp; }
}
bool _PowerIsOn;
bool _PowerIsOn;
bool _IsWarmingUp;
bool _IsCoolingDown;
/// <summary>
/// Initializes a new instance of the BasicIrDisplay class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
/// <param name="port">The IR output port</param>
/// <param name="irDriverFilepath">The path to the IR driver file</param>
public BasicIrDisplay(string key, string name, IROutputPort port, string irDriverFilepath)
: base(key, name)
{
@@ -53,74 +69,74 @@ namespace PepperDash.Essentials.Devices.Common.Displays
InputPorts.AddRange(new RoutingPortCollection<RoutingInputPort>
{
new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, new Action(Hdmi1), this, false),
new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, new Action(Hdmi2), this, false),
new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, new Action(Hdmi3), this, false),
new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, new Action(Hdmi4), this, false),
new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, new Action(Component1), this, false),
new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, new Action(Video1), this, false),
new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, new Action(Antenna), this, false),
});
}
/// <summary>
/// Hdmi1 method
/// </summary>
/// <summary>
/// Hdmi1 method
/// </summary>
public void Hdmi1()
{
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_1, IrPulseTime);
}
/// <summary>
/// Hdmi2 method
/// </summary>
/// <summary>
/// Hdmi2 method
/// </summary>
public void Hdmi2()
{
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_2, IrPulseTime);
}
/// <summary>
/// Hdmi3 method
/// </summary>
/// <summary>
/// Hdmi3 method
/// </summary>
public void Hdmi3()
{
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_3, IrPulseTime);
}
/// <summary>
/// Hdmi4 method
/// </summary>
/// <summary>
/// Hdmi4 method
/// </summary>
public void Hdmi4()
{
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_4, IrPulseTime);
}
/// <summary>
/// Component1 method
/// </summary>
/// <summary>
/// Component1 method
/// </summary>
public void Component1()
{
IrPort.Pulse(IROutputStandardCommands.IROut_COMPONENT_1, IrPulseTime);
}
/// <summary>
/// Video1 method
/// </summary>
/// <summary>
/// Video1 method
/// </summary>
public void Video1()
{
IrPort.Pulse(IROutputStandardCommands.IROut_VIDEO_1, IrPulseTime);
}
/// <summary>
/// Antenna method
/// </summary>
/// <summary>
/// Antenna method
/// </summary>
public void Antenna()
{
IrPort.Pulse(IROutputStandardCommands.IROut_ANTENNA, IrPulseTime);
@@ -128,31 +144,31 @@ namespace PepperDash.Essentials.Devices.Common.Displays
#region IPower Members
/// <summary>
/// PowerOn method
/// </summary>
/// <inheritdoc />
/// <summary>
/// PowerOn method
/// </summary>
/// <inheritdoc />
public override void PowerOn()
{
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
_PowerIsOn = true;
_PowerIsOn = true;
}
/// <summary>
/// PowerOff method
/// </summary>
/// <summary>
/// PowerOff method
/// </summary>
public override void PowerOff()
{
_PowerIsOn = false;
_PowerIsOn = false;
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
}
/// <summary>
/// PowerToggle method
/// </summary>
/// <summary>
/// PowerToggle method
/// </summary>
public override void PowerToggle()
{
_PowerIsOn = false;
_PowerIsOn = false;
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
}
@@ -160,25 +176,25 @@ namespace PepperDash.Essentials.Devices.Common.Displays
#region IBasicVolumeControls Members
/// <summary>
/// VolumeUp method
/// </summary>
/// <summary>
/// VolumeUp method
/// </summary>
public void VolumeUp(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_PLUS, pressRelease);
}
/// <summary>
/// VolumeDown method
/// </summary>
/// <summary>
/// VolumeDown method
/// </summary>
public void VolumeDown(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_MINUS, pressRelease);
}
/// <summary>
/// MuteToggle method
/// </summary>
/// <summary>
/// MuteToggle method
/// </summary>
public void MuteToggle()
{
IrPort.Pulse(IROutputStandardCommands.IROut_MUTE, 200);
@@ -190,7 +206,8 @@ namespace PepperDash.Essentials.Devices.Common.Displays
{
_IsWarmingUp = true;
IsWarmingUpFeedback.FireUpdate();
new CTimer(o => {
new CTimer(o =>
{
_IsWarmingUp = false;
IsWarmingUpFeedback.FireUpdate();
}, 10000);
@@ -213,13 +230,13 @@ namespace PepperDash.Essentials.Devices.Common.Displays
/// Typically called by the discovery routing algorithm.
/// </summary>
/// <param name="inputSelector">A delegate containing the input selector method to call</param>
/// <summary>
/// ExecuteSwitch method
/// </summary>
/// <inheritdoc />
/// <summary>
/// ExecuteSwitch method
/// </summary>
/// <inheritdoc />
public override void ExecuteSwitch(object inputSelector)
{
Debug.LogMessage(LogEventLevel.Verbose, this, "Switching to input '{0}'", (inputSelector as Action).ToString());
Debug.LogMessage(LogEventLevel.Verbose, this, "Switching to input '{0}'", (inputSelector as Action).ToString());
Action finishSwitch = () =>
{
@@ -246,42 +263,45 @@ namespace PepperDash.Essentials.Devices.Common.Displays
#endregion
/// <summary>
/// LinkToApi method
/// </summary>
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
}
/// <summary>
/// LinkToApi method
/// </summary>
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
}
}
/// <summary>
/// Represents a BasicIrDisplayFactory
/// </summary>
public class BasicIrDisplayFactory : EssentialsDeviceFactory<BasicIrDisplay>
{
public BasicIrDisplayFactory()
{
TypeNames = new List<string>() { "basicirdisplay" };
}
/// <summary>
/// Represents a BasicIrDisplayFactory
/// </summary>
public class BasicIrDisplayFactory : EssentialsDeviceFactory<BasicIrDisplay>
{
/// <summary>
/// Initializes a new instance of the BasicIrDisplayFactory class
/// </summary>
public BasicIrDisplayFactory()
{
TypeNames = new List<string>() { "basicirdisplay" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
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;
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
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;
}
}
return null;
}
}
}

View File

@@ -1,38 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Displays
{
/// <summary>
/// Defines the contract for IInputHdmi1
/// </summary>
public interface IInputHdmi1 { void InputHdmi1(); }
[Obsolete()]
public interface IInputHdmi1
{
/// <summary>
/// Switches to HDMI 1 input
/// </summary>
void InputHdmi1();
}
/// <summary>
/// Defines the contract for IInputHdmi2
/// </summary>
public interface IInputHdmi2 { void InputHdmi2(); }
[Obsolete()]
public interface IInputHdmi2
{
/// <summary>
/// Switches to HDMI 2 input
/// </summary>
void InputHdmi2();
}
/// <summary>
/// Defines the contract for IInputHdmi3
/// </summary>
public interface IInputHdmi3 { void InputHdmi3(); }
[Obsolete()]
public interface IInputHdmi3
{
/// <summary>
/// Switches to HDMI 3 input
/// </summary>
void InputHdmi3();
}
/// <summary>
/// Defines the contract for IInputHdmi4
/// </summary>
public interface IInputHdmi4 { void InputHdmi4(); }
[Obsolete()]
public interface IInputHdmi4
{
/// <summary>
/// Switches to HDMI 4 input
/// </summary>
void InputHdmi4();
}
/// <summary>
/// Defines the contract for IInputDisplayPort1
/// </summary>
public interface IInputDisplayPort1 { void InputDisplayPort1(); }
[Obsolete()]
public interface IInputDisplayPort1
{
/// <summary>
/// Switches to DisplayPort 1 input
/// </summary>
void InputDisplayPort1();
}
/// <summary>
/// Defines the contract for IInputDisplayPort2
/// </summary>
public interface IInputDisplayPort2 { void InputDisplayPort2(); }
[Obsolete()]
public interface IInputDisplayPort2
{
/// <summary>
/// Switches to DisplayPort 2 input
/// </summary>
void InputDisplayPort2();
}
/// <summary>
/// Defines the contract for IInputVga1
/// </summary>
public interface IInputVga1 { void InputVga1(); }
[Obsolete()]
public interface IInputVga1
{
/// <summary>
/// Switches to VGA 1 input
/// </summary>
void InputVga1();
}
}

View File

@@ -16,16 +16,19 @@ namespace PepperDash.Essentials.Devices.Common.Displays
/// Represents a MockDisplay
/// </summary>
public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs<string>, IRoutingSinkWithSwitchingWithInputPort, IHasPowerControlWithFeedback
{
{
/// <summary>
/// Gets or sets the Inputs
/// </summary>
public ISelectableItems<string> Inputs { get; private set; }
bool _PowerIsOn;
bool _IsWarmingUp;
bool _IsCoolingDown;
bool _PowerIsOn;
bool _IsWarmingUp;
bool _IsCoolingDown;
/// <summary>
/// Gets the power is on feedback function
/// </summary>
protected override Func<bool> PowerIsOnFeedbackFunc
{
get
@@ -34,8 +37,12 @@ namespace PepperDash.Essentials.Devices.Common.Displays
{
return _PowerIsOn;
};
} }
protected override Func<bool> IsCoolingDownFeedbackFunc
}
}
/// <summary>
/// Gets the is cooling down feedback function
/// </summary>
protected override Func<bool> IsCoolingDownFeedbackFunc
{
get
{
@@ -45,7 +52,10 @@ namespace PepperDash.Essentials.Devices.Common.Displays
};
}
}
protected override Func<bool> IsWarmingUpFeedbackFunc
/// <summary>
/// Gets the is warming up feedback function
/// </summary>
protected override Func<bool> IsWarmingUpFeedbackFunc
{
get
{
@@ -55,120 +65,128 @@ namespace PepperDash.Essentials.Devices.Common.Displays
};
}
}
/// <summary>
/// Gets the current input feedback function
/// </summary>
protected override Func<string> CurrentInputFeedbackFunc { get { return () => Inputs.CurrentItem; } }
int VolumeHeldRepeatInterval = 200;
ushort VolumeInterval = 655;
ushort _FakeVolumeLevel = 31768;
bool _IsMuted;
ushort _FakeVolumeLevel = 31768;
bool _IsMuted;
public MockDisplay(string key, string name)
: base(key, name)
{
/// <summary>
/// Initializes a new instance of the MockDisplay class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
public MockDisplay(string key, string name)
: base(key, name)
{
Inputs = new MockDisplayInputs
{
Items = new Dictionary<string, ISelectableItem>
{
{ "HDMI1", new MockDisplayInput ( "HDMI1", "HDMI 1",this ) },
{ "HDMI2", new MockDisplayInput ("HDMI2", "HDMI 2",this ) },
{ "HDMI3", new MockDisplayInput ("HDMI3", "HDMI 3",this ) },
{ "HDMI4", new MockDisplayInput ("HDMI4", "HDMI 4",this )},
{ "DP", new MockDisplayInput ("DP", "DisplayPort", this ) }
}
{
{ "HDMI1", new MockDisplayInput ( "HDMI1", "HDMI 1",this ) },
{ "HDMI2", new MockDisplayInput ("HDMI2", "HDMI 2",this ) },
{ "HDMI3", new MockDisplayInput ("HDMI3", "HDMI 3",this ) },
{ "HDMI4", new MockDisplayInput ("HDMI4", "HDMI 4",this )},
{ "DP", new MockDisplayInput ("DP", "DisplayPort", this ) }
}
};
Inputs.CurrentItemChanged += (o, a) => CurrentInputFeedback.FireUpdate();
var hdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, "HDMI1", this);
var hdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, "HDMI2", this);
var hdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, "HDMI3", this);
var hdmiIn4 = new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, "HDMI4", this);
var dpIn = new RoutingInputPort(RoutingPortNames.DisplayPortIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.DisplayPort, "DP", this);
InputPorts.AddRange(new[] { hdmiIn1, hdmiIn2, hdmiIn3, hdmiIn4, dpIn });
Inputs.CurrentItemChanged += (o, a) => CurrentInputFeedback.FireUpdate();
VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted);
var hdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, "HDMI1", this);
var hdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, "HDMI2", this);
var hdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, "HDMI3", this);
var hdmiIn4 = new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, "HDMI4", this);
var dpIn = new RoutingInputPort(RoutingPortNames.DisplayPortIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.DisplayPort, "DP", this);
InputPorts.AddRange(new[] { hdmiIn1, hdmiIn2, hdmiIn3, hdmiIn4, dpIn });
VolumeLevelFeedback = new IntFeedback("volume", () => { return _FakeVolumeLevel; });
MuteFeedback = new BoolFeedback("muteOn", () => _IsMuted);
WarmupTime = 10000;
CooldownTime = 10000;
}
}
/// <summary>
/// PowerOn method
/// </summary>
/// <inheritdoc />
public override void PowerOn()
{
if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
{
_IsWarmingUp = true;
IsWarmingUpFeedback.InvokeFireUpdate();
// Fake power-up cycle
WarmupTimer = new CTimer(o =>
{
_IsWarmingUp = false;
_PowerIsOn = true;
IsWarmingUpFeedback.InvokeFireUpdate();
PowerIsOnFeedback.InvokeFireUpdate();
}, WarmupTime);
}
}
/// <summary>
/// PowerOn method
/// </summary>
/// <inheritdoc />
public override void PowerOn()
{
if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
{
_IsWarmingUp = true;
IsWarmingUpFeedback.InvokeFireUpdate();
// Fake power-up cycle
WarmupTimer = new CTimer(o =>
{
_IsWarmingUp = false;
_PowerIsOn = true;
IsWarmingUpFeedback.InvokeFireUpdate();
PowerIsOnFeedback.InvokeFireUpdate();
}, WarmupTime);
}
}
/// <summary>
/// PowerOff method
/// </summary>
/// <inheritdoc />
public override void PowerOff()
{
// If a display has unreliable-power off feedback, just override this and
// remove this check.
if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
{
_IsCoolingDown = true;
IsCoolingDownFeedback.InvokeFireUpdate();
// Fake cool-down cycle
CooldownTimer = new CTimer(o =>
{
Debug.LogMessage(LogEventLevel.Verbose, "Cooldown timer ending", this);
_IsCoolingDown = false;
IsCoolingDownFeedback.InvokeFireUpdate();
/// <summary>
/// PowerOff method
/// </summary>
/// <inheritdoc />
public override void PowerOff()
{
// If a display has unreliable-power off feedback, just override this and
// remove this check.
if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
{
_IsCoolingDown = true;
IsCoolingDownFeedback.InvokeFireUpdate();
// Fake cool-down cycle
CooldownTimer = new CTimer(o =>
{
Debug.LogMessage(LogEventLevel.Verbose, "Cooldown timer ending", this);
_IsCoolingDown = false;
IsCoolingDownFeedback.InvokeFireUpdate();
_PowerIsOn = false;
PowerIsOnFeedback.InvokeFireUpdate();
}, CooldownTime);
}
}
/// <summary>
/// PowerToggle method
/// </summary>
/// <inheritdoc />
public override void PowerToggle()
{
if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
PowerOff();
else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
PowerOn();
}
}, CooldownTime);
}
}
/// <summary>
/// ExecuteSwitch method
/// </summary>
/// <inheritdoc />
public override void ExecuteSwitch(object selector)
{
/// <summary>
/// PowerToggle method
/// </summary>
/// <inheritdoc />
public override void PowerToggle()
{
if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
PowerOff();
else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
PowerOn();
}
/// <summary>
/// ExecuteSwitch method
/// </summary>
/// <inheritdoc />
public override void ExecuteSwitch(object selector)
{
try
{
Debug.LogMessage(LogEventLevel.Verbose, "ExecuteSwitch: {0}", this, selector);
if (!_PowerIsOn)
{
PowerOn();
}
if (!_PowerIsOn)
{
PowerOn();
}
if (!Inputs.Items.TryGetValue(selector.ToString(), out var input))
return;
@@ -184,13 +202,14 @@ namespace PepperDash.Essentials.Devices.Common.Displays
if (inputPort == null)
{
Debug.LogMessage(LogEventLevel.Verbose, "Unable to find input port for selector {selector}", this, selector);
Debug.LogMessage(LogEventLevel.Verbose, "Unable to find input port for selector {selector}", this, selector);
return;
}
Debug.LogMessage(LogEventLevel.Verbose, "Setting current input port to {inputPort}", this, inputPort);
CurrentInputPort = inputPort;
} catch (Exception ex)
}
catch (Exception ex)
{
Debug.LogMessage(ex, "Error making switch: {Exception}", this, ex);
}
@@ -201,14 +220,14 @@ namespace PepperDash.Essentials.Devices.Common.Displays
/// </summary>
public void SetInput(string selector)
{
ISelectableItem currentInput = null;
ISelectableItem currentInput = null;
try
{
currentInput = Inputs.Items.SingleOrDefault(Inputs => Inputs.Value.IsSelected).Value;
}
catch { }
try
{
currentInput = Inputs.Items.SingleOrDefault(Inputs => Inputs.Value.IsSelected).Value;
}
catch { }
if (currentInput != null)
{
@@ -216,12 +235,12 @@ namespace PepperDash.Essentials.Devices.Common.Displays
currentInput.IsSelected = false;
}
if (!Inputs.Items.TryGetValue(selector, out var input))
if (!Inputs.Items.TryGetValue(selector, out var input))
return;
input.IsSelected = true;
input.IsSelected = true;
Inputs.CurrentItem = selector;
Inputs.CurrentItem = selector;
}
@@ -232,37 +251,37 @@ namespace PepperDash.Essentials.Devices.Common.Displays
/// </summary>
public IntFeedback VolumeLevelFeedback { get; private set; }
/// <summary>
/// SetVolume method
/// </summary>
public void SetVolume(ushort level)
{
_FakeVolumeLevel = level;
VolumeLevelFeedback.InvokeFireUpdate();
}
/// <summary>
/// SetVolume method
/// </summary>
public void SetVolume(ushort level)
{
_FakeVolumeLevel = level;
VolumeLevelFeedback.InvokeFireUpdate();
}
/// <summary>
/// MuteOn method
/// </summary>
public void MuteOn()
{
_IsMuted = true;
MuteFeedback.InvokeFireUpdate();
}
/// <summary>
/// MuteOn method
/// </summary>
public void MuteOn()
{
_IsMuted = true;
MuteFeedback.InvokeFireUpdate();
}
/// <summary>
/// MuteOff method
/// </summary>
public void MuteOff()
{
_IsMuted = false;
MuteFeedback.InvokeFireUpdate();
}
/// <summary>
/// MuteOff method
/// </summary>
public void MuteOff()
{
_IsMuted = false;
MuteFeedback.InvokeFireUpdate();
}
/// <summary>
/// Gets or sets the MuteFeedback
/// </summary>
public BoolFeedback MuteFeedback { get; private set; }
/// <summary>
/// Gets or sets the MuteFeedback
/// </summary>
public BoolFeedback MuteFeedback { get; private set; }
#endregion
@@ -273,74 +292,77 @@ namespace PepperDash.Essentials.Devices.Common.Displays
/// VolumeUp method
/// </summary>
public void VolumeUp(bool pressRelease)
{
{
//while (pressRelease)
//{
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Down {0}", pressRelease);
if (pressRelease)
{
var newLevel = _FakeVolumeLevel + VolumeInterval;
SetVolume((ushort)newLevel);
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
}
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Down {0}", pressRelease);
if (pressRelease)
{
var newLevel = _FakeVolumeLevel + VolumeInterval;
SetVolume((ushort)newLevel);
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
}
//}
}
}
/// <summary>
/// VolumeDown method
/// </summary>
public void VolumeDown(bool pressRelease)
{
/// <summary>
/// VolumeDown method
/// </summary>
public void VolumeDown(bool pressRelease)
{
//while (pressRelease)
//{
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Up {0}", pressRelease);
if (pressRelease)
{
var newLevel = _FakeVolumeLevel - VolumeInterval;
SetVolume((ushort)newLevel);
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
}
Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Up {0}", pressRelease);
if (pressRelease)
{
var newLevel = _FakeVolumeLevel - VolumeInterval;
SetVolume((ushort)newLevel);
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
}
//}
}
}
/// <summary>
/// MuteToggle method
/// </summary>
public void MuteToggle()
{
_IsMuted = !_IsMuted;
MuteFeedback.InvokeFireUpdate();
}
/// <summary>
/// MuteToggle method
/// </summary>
public void MuteToggle()
{
_IsMuted = !_IsMuted;
MuteFeedback.InvokeFireUpdate();
}
#endregion
#endregion
/// <summary>
/// LinkToApi method
/// </summary>
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
}
/// <summary>
/// LinkToApi method
/// </summary>
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
}
}
/// <summary>
/// Represents a MockDisplayFactory
/// </summary>
public class MockDisplayFactory : EssentialsDeviceFactory<MockDisplay>
{
public MockDisplayFactory()
{
TypeNames = new List<string>() { "mockdisplay" , "mockdisplay2" };
}
/// <summary>
/// Represents a MockDisplayFactory
/// </summary>
public class MockDisplayFactory : EssentialsDeviceFactory<MockDisplay>
{
/// <summary>
/// Initializes a new instance of the MockDisplayFactory class
/// </summary>
public MockDisplayFactory()
{
TypeNames = new List<string>() { "mockdisplay", "mockdisplay2" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Mock Display Device");
return new MockDisplay(dc.Key, dc.Name);
}
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Mock Display Device");
return new MockDisplay(dc.Key, dc.Name);
}
}
}

View File

@@ -1,10 +1,6 @@
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials.Devices.Common.Displays
{
@@ -15,6 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.Displays
{
private Dictionary<string, ISelectableItem> _items;
/// <summary>
/// Gets or sets the collection of selectable items
/// </summary>
public Dictionary<string, ISelectableItem> Items
{
get
@@ -34,8 +33,11 @@ namespace PepperDash.Essentials.Devices.Common.Displays
private string _currentItem;
/// <summary>
/// Gets or sets the currently selected item
/// </summary>
public string CurrentItem
{
{
get
{
return _currentItem;
@@ -51,7 +53,13 @@ namespace PepperDash.Essentials.Devices.Common.Displays
}
}
/// <summary>
/// Occurs when the items collection is updated
/// </summary>
public event EventHandler ItemsUpdated;
/// <summary>
/// Occurs when the current item changes
/// </summary>
public event EventHandler CurrentItemChanged;
}
@@ -63,7 +71,10 @@ namespace PepperDash.Essentials.Devices.Common.Displays
private MockDisplay _parent;
private bool _isSelected;
/// <summary>
/// Gets or sets a value indicating whether this input is selected
/// </summary>
public bool IsSelected
{
get
@@ -91,8 +102,17 @@ namespace PepperDash.Essentials.Devices.Common.Displays
/// </summary>
public string Key { get; set; }
/// <summary>
/// Occurs when this item is updated
/// </summary>
public event EventHandler ItemUpdated;
/// <summary>
/// Initializes a new instance of the MockDisplayInput class
/// </summary>
/// <param name="key">The input key</param>
/// <param name="name">The input name</param>
/// <param name="parent">The parent mock display</param>
public MockDisplayInput(string key, string name, MockDisplay parent)
{
Key = key;
@@ -107,7 +127,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays
{
if (!_parent.PowerIsOnFeedback.BoolValue) _parent.PowerOn();
foreach(var input in _parent.Inputs.Items)
foreach (var input in _parent.Inputs.Items)
{
input.Value.IsSelected = input.Key == this.Key;
}

View File

@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.CrestronIO;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Devices.Common;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Shades
@@ -28,6 +25,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades
ISwitchedOutput LowerRelay;
ISwitchedOutput LatchedRelay;
/// <summary>
/// Gets or sets the InUpPosition
/// </summary>
public bool InUpPosition
{
get { return _isInUpPosition; }
@@ -41,10 +41,12 @@ namespace PepperDash.Essentials.Devices.Common.Shades
}
private bool _isInUpPosition { get; set; }
/// <summary>
/// Gets or sets the Type
/// </summary>
public eScreenLiftControlType Type { get; private set; }
/// <summary>
/// Gets or sets the Mode
/// </summary>
@@ -54,13 +56,20 @@ namespace PepperDash.Essentials.Devices.Common.Shades
/// Gets or sets the DisplayDeviceKey
/// </summary>
public string DisplayDeviceKey { get; private set; }
/// <summary>
/// Gets or sets the IsInUpPosition
/// </summary>
public BoolFeedback IsInUpPosition { get; private set; }
/// <summary>
/// Event that fires when the position changes
/// </summary>
public event EventHandler<EventArgs> PositionChanged;
/// <summary>
/// Constructor for ScreenLiftController
/// </summary>
public ScreenLiftController(string key, string name, ScreenLiftControllerConfigProperties config)
: base(key, name)
{
@@ -69,7 +78,7 @@ namespace PepperDash.Essentials.Devices.Common.Shades
Mode = Config.Mode;
Type = Config.Type;
IsInUpPosition = new BoolFeedback(() => _isInUpPosition);
IsInUpPosition = new BoolFeedback("isInUpPosition", () => _isInUpPosition);
switch (Mode)
{
@@ -206,14 +215,14 @@ namespace PepperDash.Essentials.Devices.Common.Shades
/// <summary>
/// Attempts to get the port on teh specified device from config
/// </summary>
/// <param name="relayConfig"></param>
/// <param name="relayKey"></param>
/// <returns></returns>
ISwitchedOutput GetSwitchedOutputFromDevice(string relayKey)
{
var portDevice = DeviceManager.GetDeviceForKey(relayKey);
if (portDevice != null)
{
return (portDevice as ISwitchedOutput);
return portDevice as ISwitchedOutput;
}
else
{
@@ -238,58 +247,14 @@ namespace PepperDash.Essentials.Devices.Common.Shades
}
/// <summary>
/// Represents a ScreenLiftControllerConfigProperties
/// </summary>
public class ScreenLiftControllerConfigProperties
{
[JsonProperty("displayDeviceKey")]
/// <summary>
/// Gets or sets the DisplayDeviceKey
/// </summary>
public string DisplayDeviceKey { get; set; }
[JsonProperty("type")]
[JsonConverter(typeof(StringEnumConverter))]
/// <summary>
/// Gets or sets the Type
/// </summary>
public eScreenLiftControlType Type { get; set; }
[JsonProperty("mode")]
[JsonConverter(typeof(StringEnumConverter))]
/// <summary>
/// Gets or sets the Mode
/// </summary>
public eScreenLiftControlMode Mode { get; set; }
[JsonProperty("relays")]
public Dictionary<string,ScreenLiftRelaysConfig> Relays { get; set; }
}
/// <summary>
/// Represents a ScreenLiftRelaysConfig
/// </summary>
public class ScreenLiftRelaysConfig
{
[JsonProperty("deviceKey")]
/// <summary>
/// Gets or sets the DeviceKey
/// </summary>
public string DeviceKey { get; set; }
[JsonProperty("pulseTimeInMs")]
/// <summary>
/// Gets or sets the PulseTimeInMs
/// </summary>
public int PulseTimeInMs { get; set; }
}
/// <summary>
/// Represents a ScreenLiftControllerFactory
/// </summary>
public class ScreenLiftControllerFactory : EssentialsDeviceFactory<RelayControlledShade>
{
/// <summary>
/// Constructor for ScreenLiftControllerFactory
/// </summary>
public ScreenLiftControllerFactory()
{
TypeNames = new List<string>() { "screenliftcontroller" };
@@ -307,13 +272,4 @@ namespace PepperDash.Essentials.Devices.Common.Shades
return new ScreenLiftController(dc.Key, dc.Name, props);
}
}
/// <summary>
/// Enumeration of eScreenLiftControlMode values
/// </summary>
public enum eScreenLiftControlMode
{
momentary,
latched
}
}

View File

@@ -0,0 +1,41 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials.Devices.Common.Shades
{
/// <summary>
/// Represents a ScreenLiftControllerConfigProperties
/// </summary>
public class ScreenLiftControllerConfigProperties
{
/// <summary>
/// Gets or sets the DisplayDeviceKey
/// </summary>
[JsonProperty("displayDeviceKey")]
public string DisplayDeviceKey { get; set; }
/// <summary>
/// Gets or sets the Type
/// </summary>
[JsonProperty("type")]
[JsonConverter(typeof(StringEnumConverter))]
public eScreenLiftControlType Type { get; set; }
/// <summary>
/// Gets or sets the Mode
/// </summary>
[JsonProperty("mode")]
[JsonConverter(typeof(StringEnumConverter))]
public eScreenLiftControlMode Mode { get; set; }
/// <summary>
/// Gets or sets the Relays
/// </summary>
[JsonProperty("relays")]
public Dictionary<string, ScreenLiftRelaysConfig> Relays { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.Shades
{
/// <summary>
/// Represents a ScreenLiftRelaysConfig
/// </summary>
public class ScreenLiftRelaysConfig
{
/// <summary>
/// Gets or sets the DeviceKey
/// </summary>
[JsonProperty("deviceKey")]
public string DeviceKey { get; set; }
/// <summary>
/// Gets or sets the PulseTimeInMs
/// </summary>
[JsonProperty("pulseTimeInMs")]
public int PulseTimeInMs { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
namespace PepperDash.Essentials.Devices.Common.Shades
{
/// <summary>
/// Enumeration of eScreenLiftControlMode values
/// </summary>
public enum eScreenLiftControlMode
{
/// <summary>
/// Momentary control mode for screen lift
/// </summary>
momentary,
/// <summary>
/// Latched control mode for screen lift
/// </summary>
latched
}
}

View File

@@ -1,9 +1,8 @@
using PepperDash.Core;
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.Devices.Common.Generic
{
@@ -12,11 +11,16 @@ namespace PepperDash.Essentials.Devices.Common.Generic
/// </summary>
public class GenericSink : EssentialsDevice, IRoutingSinkWithInputPort
{
/// <summary>
/// Initializes a new instance of the GenericSink class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
public GenericSink(string key, string name) : base(key, name)
{
InputPorts = new RoutingPortCollection<RoutingInputPort>();
var inputPort = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
var inputPort = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
InputPorts.Add(inputPort);
}
@@ -35,10 +39,12 @@ namespace PepperDash.Essentials.Devices.Common.Generic
/// <summary>
/// Gets or sets the CurrentSourceInfo
/// </summary>
public SourceListItem CurrentSourceInfo {
public SourceListItem CurrentSourceInfo
{
get => _currentSource;
set {
if(value == _currentSource)
set
{
if (value == _currentSource)
{
return;
}
@@ -51,8 +57,14 @@ namespace PepperDash.Essentials.Devices.Common.Generic
}
}
/// <summary>
/// Gets the current input port
/// </summary>
public RoutingInputPort CurrentInputPort => InputPorts[0];
/// <summary>
/// Event fired when the current source changes
/// </summary>
public event SourceInfoChangeHandler CurrentSourceChange;
}
@@ -61,6 +73,9 @@ namespace PepperDash.Essentials.Devices.Common.Generic
/// </summary>
public class GenericSinkFactory : EssentialsDeviceFactory<GenericSink>
{
/// <summary>
/// Initializes a new instance of the GenericSinkFactory class
/// </summary>
public GenericSinkFactory()
{
TypeNames = new List<string>() { "genericsink", "genericdestination" };

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
@@ -13,38 +7,43 @@ using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common
{
/// <summary>
/// Represents a GenericSource
/// </summary>
public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IUsageTracking
{
/// <summary>
/// Represents a GenericSource
/// </summary>
public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IUsageTracking
{
/// <summary>
/// Gets or sets the DisplayUiType
/// </summary>
public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } }
/// <summary>
/// Gets or sets the DisplayUiType
/// </summary>
public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } }
/// <summary>
/// Initializes a new instance of the GenericSource class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
public GenericSource(string key, string name)
: base(key, name)
{
: base(key, name)
{
AnyOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, null, this);
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { AnyOut };
}
AnyOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, null, this);
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { AnyOut };
}
#region IRoutingOutputs Members
#region IRoutingOutputs Members
/// <summary>
/// Gets or sets the AnyOut
/// </summary>
public RoutingOutputPort AnyOut { get; private set; }
/// <summary>
/// Gets or sets the OutputPorts
/// </summary>
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
/// <summary>
/// Gets or sets the AnyOut
/// </summary>
public RoutingOutputPort AnyOut { get; private set; }
/// <summary>
/// Gets or sets the OutputPorts
/// </summary>
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
#endregion
#endregion
#region IUsageTracking Members
@@ -54,13 +53,16 @@ namespace PepperDash.Essentials.Devices.Common
public UsageTracking UsageTracker { get; set; }
#endregion
}
}
/// <summary>
/// Represents a GenericSourceFactory
/// </summary>
public class GenericSourceFactory : EssentialsDeviceFactory<GenericSource>
{
/// <summary>
/// Initializes a new instance of the GenericSourceFactory class
/// </summary>
public GenericSourceFactory()
{
TypeNames = new List<string>() { "genericsource" };

View File

@@ -3,9 +3,6 @@
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;
@@ -16,134 +13,165 @@ using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Lighting
{
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
{
#region ILightingScenes Members
public event EventHandler<LightingSceneChangeEventArgs> LightingSceneChange;
/// <summary>
/// Gets or sets the LightingScenes
/// </summary>
public List<LightingScene> LightingScenes { get; protected set; }
/// <summary>
/// Gets or sets the CurrentLightingScene
/// </summary>
public LightingScene CurrentLightingScene { get; protected set; }
/// <summary>
/// Gets or sets the CurrentLightingSceneFeedback
/// Base class for lighting devices that support scenes
/// </summary>
public IntFeedback CurrentLightingSceneFeedback { get; protected set; }
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
{
#region ILightingScenes Members
#endregion
/// <summary>
/// Event fired when lighting scene changes
/// </summary>
public event EventHandler<LightingSceneChangeEventArgs> LightingSceneChange;
protected LightingBase(string key, string name)
: base(key, name)
{
LightingScenes = new List<LightingScene>();
/// <summary>
/// Gets or sets the LightingScenes
/// </summary>
public List<LightingScene> LightingScenes { get; protected set; }
CurrentLightingScene = new LightingScene();
//CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); });
}
/// <summary>
/// Gets or sets the CurrentLightingScene
/// </summary>
public LightingScene CurrentLightingScene { get; protected set; }
public abstract void SelectScene(LightingScene scene);
/// <summary>
/// Gets or sets the CurrentLightingSceneFeedback
/// </summary>
public IntFeedback CurrentLightingSceneFeedback { get; protected set; }
/// <summary>
/// SimulateSceneSelect method
/// </summary>
public void SimulateSceneSelect(string sceneName)
{
Debug.LogMessage(LogEventLevel.Debug, this, "Simulating selection of scene '{0}'", sceneName);
#endregion
var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName));
/// <summary>
/// Initializes a new instance of the LightingBase class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
protected LightingBase(string key, string name)
: base(key, name)
{
LightingScenes = new List<LightingScene>();
if (scene != null)
{
CurrentLightingScene = scene;
OnLightingSceneChange();
}
}
CurrentLightingScene = new LightingScene();
//CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); });
}
/// <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;
}
LightingSceneChange?.Invoke(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
}
/// <summary>
/// Selects the specified lighting scene
/// </summary>
/// <param name="scene">The lighting scene to select</param>
public abstract void SelectScene(LightingScene scene);
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new GenericLightingJoinMap(joinStart);
/// <summary>
/// SimulateSceneSelect method
/// </summary>
public void SimulateSceneSelect(string sceneName)
{
Debug.LogMessage(LogEventLevel.Debug, this, "Simulating selection of scene '{0}'", sceneName);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName));
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)
if (scene != null)
{
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
CurrentLightingScene = scene;
OnLightingSceneChange();
}
}
Debug.LogMessage(LogEventLevel.Information, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
/// <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;
// GenericLighitng Actions & FeedBack
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
else
scene.IsActive = false;
}
LightingSceneChange?.Invoke(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
}
var sceneIndex = 0;
/// <summary>
/// Links the lighting device to API with join map configuration
/// </summary>
/// <param name="lightingDevice">The lighting device to link</param>
/// <param name="trilist">The trilist to link to</param>
/// <param name="joinStart">The starting join number</param>
/// <param name="joinMapKey">The join map key</param>
/// <param name="bridge">The EISC API bridge</param>
/// <returns>The configured join map</returns>
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);
}
/// <summary>
/// Links the lighting device to API using an existing join map
/// </summary>
/// <param name="lightingDevice">The lighting device to link</param>
/// <param name="trilist">The trilist to link to</param>
/// <param name="joinMap">The join map to use</param>
/// <returns>The join map used for linking</returns>
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.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;
scene.IsActiveFeedback.FireUpdate();
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;
}
return joinMap;
}
}
}

View File

@@ -9,10 +9,20 @@ namespace PepperDash.Essentials.Devices.Common.Room
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IHasDefaultDisplay, IHasCurrentVolumeControls, IRoomOccupancy,
IEmergency, IMicrophonePrivacy
{
/// <summary>
/// Gets whether to exclude this room from global functions
/// </summary>
bool ExcludeFromGlobalFunctions { get; }
/// <summary>
/// Runs the route action for the given routeKey and sourceListKey
/// </summary>
/// <param name="routeKey">The route key</param>
void RunRouteAction(string routeKey);
/// <summary>
/// Gets the PropertiesConfig
/// </summary>
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
}
}

View File

@@ -12,18 +12,40 @@ namespace PepperDash.Essentials.Devices.Common.Room
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback,
IRoomOccupancy, IEmergency, IMicrophonePrivacy
{
/// <summary>
/// Gets the PropertiesConfig
/// </summary>
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
/// <summary>
/// Gets whether to exclude this room from global functions
/// </summary>
bool ExcludeFromGlobalFunctions { get; }
/// <summary>
/// Runs the route action for the given routeKey and sourceListKey
/// </summary>
/// <param name="routeKey">The route key</param>
void RunRouteAction(string routeKey);
/// <summary>
/// Gets the ScheduleSource
/// </summary>
IHasScheduleAwareness ScheduleSource { get; }
/// <summary>
/// Gets the InCallFeedback
/// </summary>
new BoolFeedback InCallFeedback { get; }
/// <summary>
/// Gets the PrivacyModeIsOnFeedback
/// </summary>
new BoolFeedback PrivacyModeIsOnFeedback { get; }
/// <summary>
/// Gets the DefaultCodecRouteString
/// </summary>
string DefaultCodecRouteString { get; }
}
}

View File

@@ -1,9 +1,4 @@
using PepperDash.Essentials.Room.Config;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PepperDash.Essentials.Devices.Common.Room
{
@@ -12,6 +7,9 @@ namespace PepperDash.Essentials.Devices.Common.Room
/// </summary>
public interface IEssentialsRoomPropertiesConfig
{
/// <summary>
/// Gets the PropertiesConfig
/// </summary>
EssentialsRoomPropertiesConfig PropertiesConfig { get; }
}
}

View File

@@ -1,9 +1,9 @@
using PepperDash.Essentials.Core;
using System.Collections.Generic;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Devices.Common.Displays;
using PepperDash.Essentials.Room.Config;
using System.Collections.Generic;
using TwoWayDisplayBase = PepperDash.Essentials.Devices.Common.Displays.TwoWayDisplayBase;
namespace PepperDash.Essentials.Devices.Common.Room
@@ -11,15 +11,31 @@ namespace PepperDash.Essentials.Devices.Common.Room
/// <summary>
/// Defines the contract for IEssentialsTechRoom
/// </summary>
public interface IEssentialsTechRoom:IEssentialsRoom, ITvPresetsProvider,IBridgeAdvanced,IRunDirectRouteAction
public interface IEssentialsTechRoom : IEssentialsRoom, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction
{
/// <summary>
/// Gets the PropertiesConfig
/// </summary>
EssentialsTechRoomConfig PropertiesConfig { get; }
/// <summary>
/// Gets the Tuners
/// </summary>
Dictionary<string, IRSetTopBoxBase> Tuners { get; }
/// <summary>
/// Gets the Displays
/// </summary>
Dictionary<string, TwoWayDisplayBase> Displays { get; }
/// <summary>
/// Powers on the room
/// </summary>
void RoomPowerOn();
/// <summary>
/// Powers off the room
/// </summary>
void RoomPowerOff();
}
}

View File

@@ -0,0 +1,41 @@
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common
{
/// <summary>
/// Represents a IRSetTopBoxBaseFactory
/// </summary>
public class IRSetTopBoxBaseFactory : EssentialsDeviceFactory<IRSetTopBoxBase>
{
/// <summary>
/// Initializes a new instance of the <see cref="IRSetTopBoxBaseFactory"/> class
/// </summary>
public IRSetTopBoxBaseFactory()
{
TypeNames = new List<string>() { "settopbox" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new SetTopBox Device");
var irCont = IRPortHelper.GetIrOutputPortController(dc);
var config = dc.Properties.ToObject<SetTopBoxPropertiesConfig>();
var stb = new IRSetTopBoxBase(dc.Key, dc.Name, irCont, config);
var listName = dc.Properties.Value<string>("presetsList");
if (listName != null)
stb.LoadPresets(listName);
return stb;
}
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Core;
namespace PepperDash.Essentials.Devices.Common
{

View File

@@ -27,6 +27,12 @@ namespace PepperDash.Essentials.Devices.Common.Shades
/// </summary>
public string StopOrPresetButtonLabel { get; set; }
/// <summary>
/// Initializes a new instance of the RelayControlledShade class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
/// <param name="config">The relay controlled shade configuration</param>
public RelayControlledShade(string key, string name, RelayControlledShadeConfigProperties config)
: base(key, name)
{
@@ -157,6 +163,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades
/// </summary>
public class RelayControlledShadeFactory : EssentialsDeviceFactory<RelayControlledShade>
{
/// <summary>
/// Initializes a new instance of the RelayControlledShadeFactory class
/// </summary>
public RelayControlledShadeFactory()
{
TypeNames = new List<string>() { "relaycontrolledshade" };

View File

@@ -1,10 +1,18 @@
using PepperDash.Essentials.Core.Shades;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Shades;
namespace PepperDash.Essentials.Devices.Common.Shades
{
/// <summary>
/// Base class for shade devices
/// </summary>
public abstract class ShadeBase : EssentialsDevice, IShadesOpenCloseStop
{
/// <summary>
/// Initializes a new instance of the ShadeBase class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
public ShadeBase(string key, string name)
: base(key, name)
{
@@ -13,8 +21,17 @@ namespace PepperDash.Essentials.Devices.Common.Shades
#region iShadesOpenClose Members
/// <summary>
/// Opens the shade
/// </summary>
public abstract void Open();
/// <summary>
/// Stops the shade
/// </summary>
public abstract void Stop();
/// <summary>
/// Closes the shade
/// </summary>
public abstract void Close();
#endregion

View File

@@ -14,8 +14,17 @@ namespace PepperDash.Essentials.Devices.Common.Shades
{
ShadeControllerConfigProperties Config;
/// <summary>
/// Gets the collection of shades controlled by this controller
/// </summary>
public List<IShadesOpenCloseStop> Shades { get; private set; }
/// <summary>
/// Initializes a new instance of the ShadeController class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
/// <param name="config">The shade controller configuration</param>
public ShadeController(string key, string name, ShadeControllerConfigProperties config)
: base(key, name)
{
@@ -76,6 +85,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades
/// </summary>
public class ShadeControllerFactory : EssentialsDeviceFactory<ShadeController>
{
/// <summary>
/// Initializes a new instance of the ShadeControllerFactory class
/// </summary>
public ShadeControllerFactory()
{
TypeNames = new List<string>() { "shadecontroller" };

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using PepperDash.Core;
@@ -22,6 +21,9 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
/// </summary>
public RoutingInputPort AnyVideoIn { get; private set; }
/// <summary>
/// Gets the CurrentInputPort
/// </summary>
public RoutingInputPort CurrentInputPort => AnyVideoIn;
#region IRoutingInputs Members
@@ -33,6 +35,11 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
#endregion
/// <summary>
/// Initializes a new instance of the <see cref="BlueJeansPc"/> class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
public BlueJeansPc(string key, string name)
: base(key, name)
{
@@ -177,30 +184,12 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
}
SourceListItem _CurrentSourceInfo;
/// <summary>
/// Event fired when the current source changes
/// </summary>
public event SourceInfoChangeHandler CurrentSourceChange;
#endregion
}
/// <summary>
/// Represents a BlueJeansPcFactory
/// </summary>
public class BlueJeansPcFactory : EssentialsDeviceFactory<BlueJeansPc>
{
public BlueJeansPcFactory()
{
TypeNames = new List<string>() { "bluejeanspc" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BlueJeansPc Device");
return new SoftCodec.BlueJeansPc(dc.Key, dc.Name);
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.SoftCodec
{
/// <summary>
/// Represents a BlueJeansPcFactory
/// </summary>
public class BlueJeansPcFactory : EssentialsDeviceFactory<BlueJeansPc>
{
/// <summary>
/// Initializes a new instance of the <see cref="BlueJeansPcFactory"/> class
/// </summary>
public BlueJeansPcFactory()
{
TypeNames = new List<string>() { "bluejeanspc" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BlueJeansPc Device");
return new BlueJeansPc(dc.Key, dc.Name);
}
}
}

View File

@@ -1,10 +1,7 @@
using Newtonsoft.Json;
using System.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.Devices.Common.SoftCodec
{
@@ -18,7 +15,8 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
/// <summary>
/// Gets or sets the CurrentInputPort
/// </summary>
public RoutingInputPort CurrentInputPort {
public RoutingInputPort CurrentInputPort
{
get => _currentInputPort;
set
{
@@ -28,19 +26,25 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
}
}
/// <summary>
/// Initializes a new instance of the <see cref="GenericSoftCodec"/> class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
/// <param name="props">The device properties</param>
public GenericSoftCodec(string key, string name, GenericSoftCodecProperties props) : base(key, name)
{
InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
for(var i = 1; i <= props.OutputCount; i++)
for (var i = 1; i <= props.OutputCount; i++)
{
var outputPort = new RoutingOutputPort($"output{i}", eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
OutputPorts.Add(outputPort);
}
for(var i = 1; i<= props.ContentInputCount; i++)
for (var i = 1; i <= props.ContentInputCount; i++)
{
var inputPort = new RoutingInputPort($"contentInput{i}", eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, $"contentInput{i}", this);
@@ -52,7 +56,7 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
return;
}
for(var i = 1; i <=props.CameraInputCount; i++)
for (var i = 1; i <= props.CameraInputCount; i++)
{
var cameraPort = new RoutingInputPort($"cameraInput{i}", eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, $"cameraInput{i}", this);
@@ -72,7 +76,11 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
/// <summary>
/// Gets or sets the CurrentSourceInfoKey
/// </summary>
public string CurrentSourceInfoKey { get ; set; }
public string CurrentSourceInfoKey { get; set; }
/// <summary>
/// Gets or sets the CurrentSourceInfo
/// </summary>
public SourceListItem CurrentSourceInfo
{
get
@@ -97,7 +105,14 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
SourceListItem _CurrentSourceInfo;
/// <summary>
/// Event fired when the current source changes
/// </summary>
public event SourceInfoChangeHandler CurrentSourceChange;
/// <summary>
/// Event fired when the input changes
/// </summary>
public event InputChangedEventHandler InputChanged;
/// <summary>
@@ -107,7 +122,7 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
{
var inputPort = InputPorts.FirstOrDefault(p => p.Selector == inputSelector);
if(inputPort == null)
if (inputPort == null)
{
Debug.LogMessage(LogEventLevel.Warning, "No input port found for selector {inputSelector}", inputSelector);
return;
@@ -116,58 +131,4 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
CurrentInputPort = inputPort;
}
}
/// <summary>
/// Represents a GenericSoftCodecProperties
/// </summary>
public class GenericSoftCodecProperties
{
[JsonProperty("hasCameraInputs")]
/// <summary>
/// Gets or sets the HasCameraInputs
/// </summary>
public bool HasCameraInputs { get; set; }
[JsonProperty("cameraInputCount")]
/// <summary>
/// Gets or sets the CameraInputCount
/// </summary>
public int CameraInputCount { get; set; }
[JsonProperty("contentInputCount")]
/// <summary>
/// Gets or sets the ContentInputCount
/// </summary>
public int ContentInputCount { get; set; }
[JsonProperty("contentOutputCount")]
/// <summary>
/// Gets or sets the OutputCount
/// </summary>
public int OutputCount { get; set; }
}
/// <summary>
/// Represents a GenericSoftCodecFactory
/// </summary>
public class GenericSoftCodecFactory: EssentialsDeviceFactory<GenericSoftCodec>
{
public GenericSoftCodecFactory()
{
TypeNames = new List<string> { "genericsoftcodec" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Attempting to create new Generic SoftCodec Device");
var props = dc.Properties.ToObject<GenericSoftCodecProperties>();
return new GenericSoftCodec(dc.Key, dc.Name, props);
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.SoftCodec
{
/// <summary>
/// Represents a GenericSoftCodecFactory
/// </summary>
public class GenericSoftCodecFactory : EssentialsDeviceFactory<GenericSoftCodec>
{
/// <summary>
/// Initializes a new instance of the <see cref="GenericSoftCodecFactory"/> class
/// </summary>
public GenericSoftCodecFactory()
{
TypeNames = new List<string> { "genericsoftcodec" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Attempting to create new Generic SoftCodec Device");
var props = dc.Properties.ToObject<GenericSoftCodecProperties>();
return new GenericSoftCodec(dc.Key, dc.Name, props);
}
}
}

View File

@@ -0,0 +1,34 @@
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.SoftCodec
{
/// <summary>
/// Represents a GenericSoftCodecProperties
/// </summary>
public class GenericSoftCodecProperties
{
/// <summary>
/// Gets or sets the HasCameraInputs
/// </summary>
[JsonProperty("hasCameraInputs")]
public bool HasCameraInputs { get; set; }
/// <summary>
/// Gets or sets the CameraInputCount
/// </summary>
[JsonProperty("cameraInputCount")]
public int CameraInputCount { get; set; }
/// <summary>
/// Gets or sets the ContentInputCount
/// </summary>
[JsonProperty("contentInputCount")]
public int ContentInputCount { get; set; }
/// <summary>
/// Gets or sets the OutputCount
/// </summary>
[JsonProperty("contentOutputCount")]
public int OutputCount { get; set; }
}
}

View File

@@ -1,71 +1,74 @@
using System;
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Sources
{
/// <summary>
/// Represents a InRoomPc
/// </summary>
public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
{
/// <summary>
/// Gets or sets the DisplayUiType
/// </summary>
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
/// <summary>
/// Gets or sets the IconName
/// </summary>
public string IconName { get; set; }
/// <summary>
/// Gets or sets the HasPowerOnFeedback
/// </summary>
public BoolFeedback HasPowerOnFeedback { get; private set; }
/// <summary>
/// Represents a InRoomPc
/// </summary>
public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
{
/// <summary>
/// Gets or sets the DisplayUiType
/// </summary>
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
/// <summary>
/// Gets or sets the IconName
/// </summary>
public string IconName { get; set; }
/// <summary>
/// Gets or sets the HasPowerOnFeedback
/// </summary>
public BoolFeedback HasPowerOnFeedback { get; private set; }
/// <summary>
/// Gets or sets the AnyVideoOut
/// </summary>
public RoutingOutputPort AnyVideoOut { get; private set; }
/// <summary>
/// Gets or sets the AnyVideoOut
/// </summary>
public RoutingOutputPort AnyVideoOut { get; private set; }
#region IRoutingOutputs Members
#region IRoutingOutputs Members
/// <summary>
/// Gets or sets the OutputPorts
/// </summary>
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
/// <summary>
/// Gets or sets the OutputPorts
/// </summary>
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
#endregion
#endregion
public InRoomPc(string key, string name)
: base(key, name)
{
IconName = "PC";
HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback",
() => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus);
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
OutputPorts.Add(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.None, 0, this));
}
/// <summary>
/// Initializes a new instance of the <see cref="InRoomPc"/> class
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
public InRoomPc(string key, string name)
: base(key, name)
{
IconName = "PC";
HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback",
() => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus);
#region IHasFeedback Members
OutputPorts = new RoutingPortCollection<RoutingOutputPort>
{
(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.None, 0, this))
};
}
/// <summary>
/// Passes through the VideoStatuses list
/// </summary>
#region IHasFeedback Members
/// <summary>
/// Passes through the VideoStatuses list
/// </summary>
public FeedbackCollection<Feedback> Feedbacks
{
get
{
get
{
var newList = new FeedbackCollection<Feedback>();
newList.AddRange(this.GetVideoStatuses().ToList());
return newList;
}
}
}
#endregion
#endregion
#region IUsageTracking Members
@@ -75,27 +78,6 @@ namespace PepperDash.Essentials.Devices.Common.Sources
public UsageTracking UsageTracker { get; set; }
#endregion
}
/// <summary>
/// Represents a InRoomPcFactory
/// </summary>
public class InRoomPcFactory : EssentialsDeviceFactory<InRoomPc>
{
public InRoomPcFactory()
{
TypeNames = new List<string>() { "inroompc" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new InRoomPc Device");
return new InRoomPc(dc.Key, dc.Name);
}
}
}

View File

@@ -0,0 +1,33 @@
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Sources
{
/// <summary>
/// Represents a InRoomPcFactory
/// </summary>
public class InRoomPcFactory : EssentialsDeviceFactory<InRoomPc>
{
/// <summary>
/// Initializes a new instance of the <see cref="InRoomPcFactory"/> class
/// </summary>
public InRoomPcFactory()
{
TypeNames = new List<string>() { "inroompc" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new InRoomPc Device");
return new InRoomPc(dc.Key, dc.Name);
}
}
}

View File

@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Sources
{
@@ -11,54 +6,59 @@ namespace PepperDash.Essentials.Devices.Common.Sources
/// Represents a Laptop
/// </summary>
public class Laptop : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
{
/// <summary>
/// Gets or sets the DisplayUiType
/// </summary>
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
/// <summary>
/// Gets or sets the IconName
/// </summary>
public string IconName { get; set; }
/// <summary>
/// Gets or sets the HasPowerOnFeedback
/// </summary>
public BoolFeedback HasPowerOnFeedback { get; private set; }
{
/// <summary>
/// Gets or sets the DisplayUiType
/// </summary>
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
/// <summary>
/// Gets or sets the IconName
/// </summary>
public string IconName { get; set; }
/// <summary>
/// Gets or sets the HasPowerOnFeedback
/// </summary>
public BoolFeedback HasPowerOnFeedback { get; private set; }
/// <summary>
/// Gets or sets the AnyVideoOut
/// </summary>
public RoutingOutputPort AnyVideoOut { get; private set; }
/// <summary>
/// Gets or sets the AnyVideoOut
/// </summary>
public RoutingOutputPort AnyVideoOut { get; private set; }
#region IRoutingOutputs Members
#region IRoutingOutputs Members
/// <summary>
/// Gets or sets the OutputPorts
/// </summary>
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
/// <summary>
/// Gets or sets the OutputPorts
/// </summary>
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
#endregion
#endregion
public Laptop(string key, string name)
: base(key, name)
{
IconName = "Laptop";
/// <summary>
/// Initializes a new instance of the Laptop class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
public Laptop(string key, string name)
: base(key, name)
{
IconName = "Laptop";
HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback",
() => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus);
HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback",
() => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus);
OutputPorts = new RoutingPortCollection<RoutingOutputPort>
OutputPorts = new RoutingPortCollection<RoutingOutputPort>
{
(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.None, 0, this))
};
}
}
#region IHasFeedback Members
#region IHasFeedback Members
/// <summary>
/// Passes through the VideoStatuses list
/// </summary>
/// <summary>
/// Passes through the VideoStatuses list
/// </summary>
public FeedbackCollection<Feedback> Feedbacks
{
get
@@ -69,7 +69,7 @@ namespace PepperDash.Essentials.Devices.Common.Sources
}
}
#endregion
#endregion
#region IUsageTracking Members
@@ -79,26 +79,5 @@ namespace PepperDash.Essentials.Devices.Common.Sources
public UsageTracking UsageTracker { get; set; }
#endregion
}
/// <summary>
/// Represents a LaptopFactory
/// </summary>
public class LaptopFactory : EssentialsDeviceFactory<Laptop>
{
public LaptopFactory()
{
TypeNames = new List<string>() { "laptop" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Laptop Device");
return new Laptop(dc.Key, dc.Name);
}
}
}

View File

@@ -0,0 +1,32 @@
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Sources
{
/// <summary>
/// Represents a LaptopFactory
/// </summary>
public class LaptopFactory : EssentialsDeviceFactory<Laptop>
{
/// <summary>
/// Initializes a new instance of the <see cref="LaptopFactory"/> class
/// </summary>
public LaptopFactory()
{
TypeNames = new List<string>() { "laptop" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Laptop Device");
return new Laptop(dc.Key, dc.Name);
}
}
}

View File

@@ -1,60 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using System.Linq;
using System.Reflection;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common
{
/// <summary>
/// Represents a AppleTV
/// Wrapper class for an IR-Controlled AppleTV
/// </summary>
[Description("Wrapper class for an IR-Controlled AppleTV")]
/// <summary>
/// Represents a AppleTV
/// </summary>
public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource, IRoutingOutputs
public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource, IRoutingOutputs
{
/// <summary>
/// Gets or sets the IrPort
/// </summary>
/// <summary>
/// Gets or sets the IrPort
/// </summary>
public IrOutputPortController IrPort { get; private set; }
/// <summary>
/// Standard Driver Name
/// </summary>
public const string StandardDriverName = "Apple_AppleTV_4th_Gen_Essentials.ir";
/// <summary>
/// Gets or sets the DisplayUiType
/// </summary>
public uint DisplayUiType { get { return DisplayUiConstants.TypeAppleTv; } }
/// <summary>
/// Gets or sets the DisplayUiType
/// </summary>
public uint DisplayUiType { get { return DisplayUiConstants.TypeAppleTv; } }
public AppleTV(string key, string name, IrOutputPortController portCont)
: base(key, name)
{
IrPort = portCont;
DeviceManager.AddDevice(portCont);
/// <summary>
/// Initializes a new instance of the <see cref="AppleTV"/> class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
/// <param name="portCont">The IR output port controller</param>
public AppleTV(string key, string name, IrOutputPortController portCont)
: base(key, name)
{
IrPort = portCont;
DeviceManager.AddDevice(portCont);
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, null, this);
AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio,
eRoutingPortConnectionType.DigitalAudio, null, this);
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { HdmiOut, AnyAudioOut };
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, null, this);
AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio,
eRoutingPortConnectionType.DigitalAudio, null, this);
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { HdmiOut, AnyAudioOut };
PrintExpectedIrCommands();
}
}
/// <summary>
/// PrintExpectedIrCommands method
/// </summary>
public void PrintExpectedIrCommands()
{
var cmds = typeof (AppleTvIrCommands).GetFields(BindingFlags.Public | BindingFlags.Static);
var cmds = typeof(AppleTvIrCommands).GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (var value in cmds.Select(cmd => cmd.GetValue(null)).OfType<string>())
{
@@ -64,151 +67,158 @@ namespace PepperDash.Essentials.Devices.Common
#region IDPad Members
/// <summary>
/// Up method
/// </summary>
public void Up(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Up, pressRelease);
}
/// <summary>
/// Up method
/// </summary>
public void Up(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Up, pressRelease);
}
/// <summary>
/// Down method
/// </summary>
public void Down(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Down, pressRelease);
}
/// <summary>
/// Down method
/// </summary>
public void Down(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Down, pressRelease);
}
/// <summary>
/// Left method
/// </summary>
public void Left(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Left, pressRelease);
}
/// <summary>
/// Left method
/// </summary>
public void Left(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Left, pressRelease);
}
/// <summary>
/// Right method
/// </summary>
public void Right(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Right, pressRelease);
}
/// <summary>
/// Right method
/// </summary>
public void Right(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Right, pressRelease);
}
/// <summary>
/// Select method
/// </summary>
public void Select(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Enter, pressRelease);
}
/// <summary>
/// Select method
/// </summary>
public void Select(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Enter, pressRelease);
}
/// <summary>
/// Menu method
/// </summary>
public void Menu(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Menu, pressRelease);
}
/// <summary>
/// Menu method
/// </summary>
public void Menu(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.Menu, pressRelease);
}
/// <summary>
/// Exit method
/// </summary>
public void Exit(bool pressRelease)
{
/// <summary>
/// Exit method
/// </summary>
public void Exit(bool pressRelease)
{
}
}
#endregion
#endregion
#region ITransport Members
#region ITransport Members
/// <summary>
/// Play method
/// </summary>
public void Play(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.PlayPause, pressRelease);
}
/// <summary>
/// Pause method
/// </summary>
public void Pause(bool pressRelease)
{
/// <summary>
/// Play method
/// </summary>
public void Play(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.PlayPause, pressRelease);
}
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
/// <summary>
/// Rewind method
/// </summary>
public void Rewind(bool pressRelease)
{
}
/// <summary>
/// Pause method
/// </summary>
public void Pause(bool pressRelease)
{
IrPort.PressRelease(AppleTvIrCommands.PlayPause, pressRelease);
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
public void FFwd(bool pressRelease)
{
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
/// <summary>
/// Rewind method
/// </summary>
public void Rewind(bool pressRelease)
{
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
public void ChapMinus(bool pressRelease)
{
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
public void FFwd(bool pressRelease)
{
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
public void ChapPlus(bool pressRelease)
{
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
public void ChapMinus(bool pressRelease)
{
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
public void Stop(bool pressRelease)
{
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
public void ChapPlus(bool pressRelease)
{
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
public void Record(bool pressRelease)
{
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
public void Stop(bool pressRelease)
{
}
#endregion
/// <summary>
/// Not implemented
/// </summary>
/// <param name="pressRelease"></param>
public void Record(bool pressRelease)
{
}
#region IRoutingOutputs Members
#endregion
public RoutingOutputPort HdmiOut { get; private set; }
public RoutingOutputPort AnyAudioOut { get; private set; }
/// <summary>
/// Gets or sets the OutputPorts
/// </summary>
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
#region IRoutingOutputs Members
#endregion
/// <summary>
/// Gets the HdmiOut
/// </summary>
public RoutingOutputPort HdmiOut { get; private set; }
/// <summary>
/// LinkToApi method
/// </summary>
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
/// <summary>
/// Gets the AnyAudioOut
/// </summary>
public RoutingOutputPort AnyAudioOut { get; private set; }
/// <summary>
/// Gets or sets the OutputPorts
/// </summary>
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
#endregion
/// <summary>
/// LinkToApi method
/// </summary>
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new AppleTvJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
@@ -235,42 +245,6 @@ namespace PepperDash.Essentials.Devices.Common
trilist.SetBoolSigAction(joinMap.Select.JoinNumber, Select);
trilist.SetBoolSigAction(joinMap.Menu.JoinNumber, Menu);
trilist.SetBoolSigAction(joinMap.PlayPause.JoinNumber, Play);
}
}
/// <summary>
/// Represents a AppleTVFactory
/// </summary>
public class AppleTVFactory : EssentialsDeviceFactory<AppleTV>
{
public AppleTVFactory()
{
TypeNames = new List<string>() { "appletv" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new AppleTV Device");
var irCont = IRPortHelper.GetIrOutputPortController(dc);
return new AppleTV(dc.Key, dc.Name, irCont);
}
}
public static class AppleTvIrCommands
{
public static string Up = "+";
public static string Down = "-";
public static string Left = IROutputStandardCommands.IROut_TRACK_MINUS;
public static string Right = IROutputStandardCommands.IROut_TRACK_PLUS;
public static string Enter = IROutputStandardCommands.IROut_ENTER;
public static string PlayPause = "PLAY/PAUSE";
public static string Rewind = "REWIND";
public static string Menu = "Menu";
public static string FastForward = "FASTFORWARD";
}
}

View File

@@ -0,0 +1,33 @@
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common
{
/// <summary>
/// Represents a AppleTVFactory
/// </summary>
public class AppleTVFactory : EssentialsDeviceFactory<AppleTV>
{
/// <summary>
/// Initializes a new instance of the <see cref="AppleTVFactory"/> class
/// </summary>
public AppleTVFactory()
{
TypeNames = new List<string>() { "appletv" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new AppleTV Device");
var irCont = IRPortHelper.GetIrOutputPortController(dc);
return new AppleTV(dc.Key, dc.Name, irCont);
}
}
}

View File

@@ -0,0 +1,56 @@
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Devices.Common
{
/// <summary>
/// Represents AppleTvIrCommands
/// </summary>
public static class AppleTvIrCommands
{
/// <summary>
/// Up command
/// </summary>
public static string Up = "+";
/// <summary>
/// Down command
/// </summary>
public static string Down = "-";
/// <summary>
/// Left command
/// </summary>
public static string Left = IROutputStandardCommands.IROut_TRACK_MINUS;
/// <summary>
/// Right command
/// </summary>
public static string Right = IROutputStandardCommands.IROut_TRACK_PLUS;
/// <summary>
/// Enter command
/// </summary>
public static string Enter = IROutputStandardCommands.IROut_ENTER;
/// <summary>
/// PlayPause command
/// </summary>
public static string PlayPause = "PLAY/PAUSE";
/// <summary>
/// Rewind command
/// </summary>
public static string Rewind = "REWIND";
/// <summary>
/// Menu command
/// </summary>
public static string Menu = "Menu";
/// <summary>
/// FastForward command
/// </summary>
public static string FastForward = "FASTFORWARD";
}
}

View File

@@ -1,107 +1,106 @@
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 Crestron.SimplSharpPro;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common
{
[Description("Wrapper class for an IR-Controlled Roku")]
/// <summary>
/// Represents a Roku2
/// </summary>
/// <summary>
/// Represents a Roku2
/// Wrapper class for an IR-Controlled Roku
/// </summary>
[Description("Wrapper class for an IR-Controlled Roku")]
public class Roku2 : EssentialsDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource, IRoutingOutputs
{
/// <summary>
/// Gets or sets the IrPort
/// </summary>
[Api]
/// <summary>
/// Gets or sets the IrPort
/// </summary>
public IrOutputPortController IrPort { get; private set; }
/// <summary>
/// Standard Driver Name
/// </summary>
public const string StandardDriverName = "Roku XD_S.ir";
/// <summary>
/// Gets or sets the DisplayUiType
/// </summary>
[Api]
/// <summary>
/// Gets or sets the DisplayUiType
/// </summary>
public uint DisplayUiType { get { return DisplayUiConstants.TypeRoku; } }
/// <summary>
/// Initializes a new instance of the <see cref="Roku2"/> class
/// </summary>
public Roku2(string key, string name, IrOutputPortController portCont)
: base(key, name)
{
IrPort = portCont;
DeviceManager.AddDevice(portCont);;
DeviceManager.AddDevice(portCont); ;
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, null, this);
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { HdmiOut };
}
#region IDPad Members
/// <summary>
/// Up method
/// </summary>
[Api]
/// <summary>
/// Up method
/// </summary>
public void Up(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_UP_ARROW, pressRelease);
}
/// <summary>
/// Down method
/// </summary>
[Api]
/// <summary>
/// Down method
/// </summary>
public void Down(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_DN_ARROW, pressRelease);
}
/// <summary>
/// Left method
/// </summary>
[Api]
/// <summary>
/// Left method
/// </summary>
public void Left(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_LEFT_ARROW, pressRelease);
}
/// <summary>
/// Right method
/// </summary>
[Api]
/// <summary>
/// Right method
/// </summary>
public void Right(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_RIGHT_ARROW, pressRelease);
}
/// <summary>
/// Select method
/// </summary>
[Api]
/// <summary>
/// Select method
/// </summary>
public void Select(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_ENTER, pressRelease);
}
/// <summary>
/// Menu method
/// </summary>
[Api]
/// <summary>
/// Menu method
/// </summary>
public void Menu(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_MENU, pressRelease);
}
/// <summary>
/// Exit method
/// </summary>
[Api]
/// <summary>
/// Exit method
/// </summary>
public void Exit(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_EXIT, pressRelease);
@@ -111,49 +110,46 @@ namespace PepperDash.Essentials.Devices.Common
#region ITransport Members
/// <summary>
/// Play method
/// </summary>
[Api]
/// <summary>
/// Play method
/// </summary>
public void Play(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_PLAY, pressRelease);
}
/// <summary>
/// Pause method
/// </summary>
[Api]
/// <summary>
/// Pause method
/// </summary>
public void Pause(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_PAUSE, pressRelease);
}
/// <summary>
/// Rewind method
/// </summary>
[Api]
/// <summary>
/// Rewind method
/// </summary>
public void Rewind(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease);
}
/// <summary>
/// FFwd method
/// </summary>
[Api]
/// <summary>
/// FFwd method
/// </summary>
public void FFwd(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_FSCAN, pressRelease);
}
/// <summary>
/// Not implemented
/// ChapMinus method - Not implemented
/// </summary>
/// <param name="pressRelease"></param>
/// <summary>
/// ChapMinus method
/// </summary>
public void ChapMinus(bool pressRelease)
{
}
@@ -186,34 +182,18 @@ namespace PepperDash.Essentials.Devices.Common
#region IRoutingOutputs Members
/// <summary>
/// HdmiOut
/// </summary>
public RoutingOutputPort HdmiOut { get; private set; }
/// <summary>
/// OutputPorts
/// </summary>
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
#endregion
}
/// <summary>
/// Represents a Roku2Factory
/// </summary>
public class Roku2Factory : EssentialsDeviceFactory<Roku2>
{
public Roku2Factory()
{
TypeNames = new List<string>() { "roku" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Roku Device");
var irCont = IRPortHelper.GetIrOutputPortController(dc);
return new Roku2(dc.Key, dc.Name, irCont);
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common
{
/// <summary>
/// Represents a Roku2Factory
/// </summary>
public class Roku2Factory : EssentialsDeviceFactory<Roku2>
{
/// <summary>
/// Roku2Factory constructor
/// </summary>
public Roku2Factory()
{
TypeNames = new List<string>() { "roku" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Roku Device");
var irCont = IRPortHelper.GetIrOutputPortController(dc);
return new Roku2(dc.Key, dc.Name, irCont);
}
}
}

View File

@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{

View File

@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core.Presets;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
@@ -38,19 +36,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// </summary>
/// <param name="preset"></param>
/// <param name="description"></param>
void CodecRoomPresetStore(int preset, string description);
void CodecRoomPresetStore(int preset, string description);
/// <summary>
/// Selects a far end preset by its ID. This is typically used to recall a preset that has been defined on the far end codec.
/// </summary>
/// <param name="preset"></param>
void SelectFarEndPreset(int preset);
void SelectFarEndPreset(int preset);
}
/// <summary>
/// Static class for converting non-generic RoomPresets to generic CameraPresets.
/// </summary>
public static class RoomPresets
public static class RoomPresets
{
/// <summary>
/// Converts non-generic RoomPresets to generic CameraPresets

View File

@@ -3,5 +3,23 @@
/// <summary>
/// Enumeration of eExternalSourceMode values
/// </summary>
public enum eExternalSourceMode {Ready, NotReady, Hidden, Error}
public enum eExternalSourceMode
{
/// <summary>
/// Ready state
/// </summary>
Ready,
/// <summary>
/// Not ready state
/// </summary>
NotReady,
/// <summary>
/// Hidden state
/// </summary>
Hidden,
/// <summary>
/// Error state
/// </summary>
Error
}
}

View File

@@ -3,5 +3,35 @@
/// <summary>
/// Enumeration of eExternalSourceType values
/// </summary>
public enum eExternalSourceType {camera, desktop, document_camera, mediaplayer, PC, whiteboard, other}
public enum eExternalSourceType
{
/// <summary>
/// Camera source type
/// </summary>
camera,
/// <summary>
/// Desktop source type
/// </summary>
desktop,
/// <summary>
/// Document camera source type
/// </summary>
document_camera,
/// <summary>
/// Media player source type
/// </summary>
mediaplayer,
/// <summary>
/// PC source type
/// </summary>
PC,
/// <summary>
/// Whiteboard source type
/// </summary>
whiteboard,
/// <summary>
/// Other source type
/// </summary>
other
}
}

View File

@@ -0,0 +1,31 @@
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
/// <summary>
/// Represents a CodecCommandWithLabel
/// </summary>
public class CodecCommandWithLabel
{
/// <summary>
/// Gets or sets the Command
/// </summary>
public string Command { get; private set; }
/// <summary>
/// Gets or sets the Label
/// </summary>
public string Label { get; private set; }
/// <summary>
/// Constructor for <see cref="CodecCommandWithLabel"/>
/// </summary>
/// <param name="command">Command string</param>
/// <param name="label">Label string</param>
public CodecCommandWithLabel(string command, string label)
{
Command = command;
Label = label;
}
}
}

View File

@@ -0,0 +1,150 @@
using System;
using PepperDash.Core;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
/// <summary>
/// Represents a CodecPhonebookSyncState
/// </summary>
public class CodecPhonebookSyncState : IKeyed
{
private bool _InitialSyncComplete;
/// <summary>
/// Constructor for CodecPhonebookSyncState
/// </summary>
/// <param name="key">Key for the codec phonebook sync state</param>
public CodecPhonebookSyncState(string key)
{
Key = key;
CodecDisconnected();
}
/// <summary>
/// Gets or sets the InitialSyncComplete
/// </summary>
public bool InitialSyncComplete
{
get { return _InitialSyncComplete; }
private set
{
if (value == true)
{
InitialSyncCompleted?.Invoke(this, new EventArgs());
}
_InitialSyncComplete = value;
}
}
/// <summary>
/// Gets or sets the InitialPhonebookFoldersWasReceived
/// </summary>
public bool InitialPhonebookFoldersWasReceived { get; private set; }
/// <summary>
/// Gets or sets the NumberOfContactsWasReceived
/// </summary>
public bool NumberOfContactsWasReceived { get; private set; }
/// <summary>
/// Gets or sets the PhonebookRootEntriesWasRecieved
/// </summary>
public bool PhonebookRootEntriesWasRecieved { get; private set; }
/// <summary>
/// Gets or sets the PhonebookHasFolders
/// </summary>
public bool PhonebookHasFolders { get; private set; }
/// <summary>
/// Gets or sets the NumberOfContacts
/// </summary>
public int NumberOfContacts { get; private set; }
#region IKeyed Members
/// <summary>
/// Gets or sets the Key
/// </summary>
public string Key { get; private set; }
#endregion
/// <summary>
/// Event InitialSyncCompleted
/// </summary>
public event EventHandler<EventArgs> InitialSyncCompleted;
/// <summary>
/// InitialPhonebookFoldersReceived method
/// </summary>
public void InitialPhonebookFoldersReceived()
{
InitialPhonebookFoldersWasReceived = true;
CheckSyncStatus();
}
/// <summary>
/// PhonebookRootEntriesReceived method
/// </summary>
public void PhonebookRootEntriesReceived()
{
PhonebookRootEntriesWasRecieved = true;
CheckSyncStatus();
}
/// <summary>
/// SetPhonebookHasFolders method
/// </summary>
public void SetPhonebookHasFolders(bool value)
{
PhonebookHasFolders = value;
Debug.LogMessage(LogEventLevel.Debug, this, "Phonebook has folders: {0}", PhonebookHasFolders);
}
/// <summary>
/// SetNumberOfContacts method
/// </summary>
public void SetNumberOfContacts(int contacts)
{
NumberOfContacts = contacts;
NumberOfContactsWasReceived = true;
Debug.LogMessage(LogEventLevel.Debug, this, "Phonebook contains {0} contacts.", NumberOfContacts);
CheckSyncStatus();
}
/// <summary>
/// CodecDisconnected method
/// </summary>
public void CodecDisconnected()
{
InitialPhonebookFoldersWasReceived = false;
PhonebookHasFolders = false;
NumberOfContacts = 0;
NumberOfContactsWasReceived = false;
}
private void CheckSyncStatus()
{
if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved)
{
InitialSyncComplete = true;
Debug.LogMessage(LogEventLevel.Debug, this, "Initial Phonebook Sync Complete!");
}
else
{
InitialSyncComplete = false;
}
}
}
}

View File

@@ -2,8 +2,15 @@
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
/// <summary>
/// Base class for presets that can be converted to PresetBase
/// </summary>
public abstract class ConvertiblePreset
{
/// <summary>
/// Converts the preset to a PresetBase
/// </summary>
/// <returns><see cref="PresetBase"/></returns>
public abstract PresetBase ConvertCodecPreset();
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
/// <summary>
/// Represents a CodecParticipants
/// </summary>
public class CodecParticipants
{
private List<Participant> _currentParticipants;
/// <summary>
/// Gets or sets the CurrentParticipants
/// </summary>
public List<Participant> CurrentParticipants
{
get { return _currentParticipants; }
set
{
_currentParticipants = value;
OnParticipantsChanged();
}
}
/// <summary>
/// Gets the Host participant
/// </summary>
public Participant Host
{
get
{
return _currentParticipants.FirstOrDefault(p => p.IsHost);
}
}
/// <summary>
/// Event fired when the participants list has changed
/// </summary>
public event EventHandler<EventArgs> ParticipantsListHasChanged;
/// <summary>
/// Initializes a new instance of the CodecParticipants class
/// </summary>
public CodecParticipants()
{
_currentParticipants = new List<Participant>();
}
/// <summary>
/// OnParticipantsChanged method
/// </summary>
public void OnParticipantsChanged()
{
var handler = ParticipantsListHasChanged;
if (handler == null) return;
handler(this, new EventArgs());
}
}
}

View File

@@ -1,14 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using Newtonsoft.Json;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
@@ -17,10 +7,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// </summary>
public interface IHasCodecLayouts
{
/// <summary>
/// Feedback that indicates the current layout on the local display
/// </summary>
StringFeedback LocalLayoutFeedback { get; }
/// <summary>
/// Toggles the local layout
/// </summary>
void LocalLayoutToggle();
void LocalLayoutToggleSingleProminent();
void MinMaxLayoutToggle();
/// <summary>
/// Toggles the local layout to single prominent
/// </summary>
void LocalLayoutToggleSingleProminent();
/// <summary>
/// Toggle the MinMax layout
/// </summary>
void MinMaxLayoutToggle();
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
@@ -13,14 +7,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// </summary>
public interface IHasCodecSelfView
{
/// <summary>
/// Feedback that indicates whether Selfview is on
/// </summary>
BoolFeedback SelfviewIsOnFeedback { get; }
/// <summary>
/// Setting that indicates whether the device shows selfview by default
/// </summary>
bool ShowSelfViewByDefault { get; }
/// <summary>
/// Turns selfview on
/// </summary>
void SelfViewModeOn();
/// <summary>
/// Turns selfview off
/// </summary>
void SelfViewModeOff();
/// <summary>
/// Toggles selfview mode
/// </summary>
void SelfViewModeToggle();
}
}

View File

@@ -1,12 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
@@ -15,94 +9,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
/// </summary>
public interface IHasMeetingInfo
{
/// <summary>
/// Raised when meeting info changes
/// </summary>
event EventHandler<MeetingInfoEventArgs> MeetingInfoChanged;
/// <summary>
/// Gets the current meeting information
/// </summary>
MeetingInfo MeetingInfo { get; }
}
/// <summary>
/// Represents a MeetingInfo
/// </summary>
public class MeetingInfo
{
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the Id
/// </summary>
public string Id { get; private set; }
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; private set; }
[JsonProperty("host", NullValueHandling = NullValueHandling.Ignore)]
public string Host { get; private set; }
[JsonProperty("password", NullValueHandling = NullValueHandling.Ignore)]
public string Password { get; private set; }
[JsonProperty("shareStatus", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the ShareStatus
/// </summary>
public string ShareStatus { get; private set; }
[JsonProperty("isHost", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the IsHost
/// </summary>
public Boolean IsHost { get; private set; }
[JsonProperty("isSharingMeeting", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the IsSharingMeeting
/// </summary>
public Boolean IsSharingMeeting { get; private set; }
[JsonProperty("waitingForHost", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the WaitingForHost
/// </summary>
public Boolean WaitingForHost { get; private set; }
[JsonProperty("isLocked", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the IsLocked
/// </summary>
public Boolean IsLocked { get; private set; }
[JsonProperty("isRecording", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the IsRecording
/// </summary>
public Boolean IsRecording { get; private set; }
[JsonProperty("canRecord", NullValueHandling = NullValueHandling.Ignore)]
/// <summary>
/// Gets or sets the CanRecord
/// </summary>
public Boolean CanRecord { get; private set; }
public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost, bool isLocked, bool isRecording, bool canRecord)
{
Id = id;
Name = name;
Host = host;
Password = password;
ShareStatus = shareStatus;
IsHost = isHost;
IsSharingMeeting = isSharingMeeting;
WaitingForHost = waitingForHost;
IsLocked = isLocked;
IsRecording = isRecording;
CanRecord = CanRecord;
}
}
/// <summary>
/// Represents a MeetingInfoEventArgs
/// </summary>
public class MeetingInfoEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the Info
/// </summary>
public MeetingInfo Info { get; private set; }
public MeetingInfoEventArgs(MeetingInfo info)
{
Info = info;
}
}
}

View File

@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
@@ -12,10 +7,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
/// </summary>
public interface IHasMeetingLock
{
/// <summary>
/// Feedback that indicates whether the meeting is locked
/// </summary>
BoolFeedback MeetingIsLockedFeedback { get; }
/// <summary>
/// Locks the meeting
/// </summary>
void LockMeeting();
/// <summary>
/// Unlocks the meeting
/// </summary>
void UnLockMeeting();
/// <summary>
/// Toggles the meeting lock state
/// </summary>
void ToggleMeetingLock();
}
}

View File

@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
@@ -12,24 +7,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
/// </summary>
public interface IHasMeetingRecording
{
/// <summary>
/// Feedback that indicates whether the meeting is being recorded
/// </summary>
BoolFeedback MeetingIsRecordingFeedback { get; }
/// <summary>
/// Starts recording the meeting
/// </summary>
void StartRecording();
void StopRecording();
void ToggleRecording();
}
/// <summary>
/// Defines the contract for IHasMeetingRecordingWithPrompt
/// </summary>
public interface IHasMeetingRecordingWithPrompt : IHasMeetingRecording
{
BoolFeedback RecordConsentPromptIsVisible { get; }
/// <summary>
/// Used to agree or disagree to the meeting being recorded when prompted
/// Stops recording the meeting
/// </summary>
/// <param name="agree"></param>
void RecordingPromptAcknowledgement(bool agree);
void StopRecording();
/// <summary>
/// Toggles recording the meeting
/// </summary>
void ToggleRecording();
}
}

View File

@@ -0,0 +1,21 @@
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
/// <summary>
/// Defines the contract for IHasMeetingRecordingWithPrompt
/// </summary>
public interface IHasMeetingRecordingWithPrompt : IHasMeetingRecording
{
/// <summary>
/// Feedback that indicates whether the recording consent prompt is visible
/// </summary>
BoolFeedback RecordConsentPromptIsVisible { get; }
/// <summary>
/// Used to agree or disagree to the meeting being recorded when prompted
/// </summary>
/// <param name="agree"></param>
void RecordingPromptAcknowledgement(bool agree);
}
}

View File

@@ -0,0 +1,31 @@
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
/// <summary>
/// Defines the contract for IHasParticipantAudioMute
/// </summary>
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
{
/// <summary>
/// Mute audio of all participants
/// </summary>
void MuteAudioForAllParticipants();
/// <summary>
/// Mute audio for participant
/// </summary>
/// <param name="userId">The user ID of the participant to mute</param>
void MuteAudioForParticipant(int userId);
/// <summary>
/// Unmute audio for participant
/// </summary>
/// <param name="userId">The user ID of the participant to unmute</param>
void UnmuteAudioForParticipant(int userId);
/// <summary>
/// Toggles audio for participant
/// </summary>
/// <param name="userId">The user ID of the participant to toggle</param>
void ToggleAudioForParticipant(int userId);
}
}

View File

@@ -0,0 +1,40 @@
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
/// <summary>
/// Defines the contract for IHasParticipantPinUnpin
/// </summary>
public interface IHasParticipantPinUnpin : IHasParticipants
{
/// <summary>
/// Feedback that indicates the number of screens available for pinning participants
/// </summary>
IntFeedback NumberOfScreensFeedback { get; }
/// <summary>
/// Gets the screen index to pin the user to
/// </summary>
int ScreenIndexToPinUserTo { get; }
/// <summary>
/// Pins a participant to a screen
/// </summary>
/// <param name="userId">The user ID of the participant to pin</param>
/// <param name="screenIndex">The screen index to pin the user to</param>
void PinParticipant(int userId, int screenIndex);
/// <summary>
/// Unpins a participant
/// </summary>
/// <param name="userId">The user ID of the participant to unpin</param>
void UnPinParticipant(int userId);
/// <summary>
/// Toggles the pin state of a participant
/// </summary>
/// <param name="userId">The user ID of the participant to toggle</param>
/// <param name="screenIndex">The screen index to pin the user to</param>
void ToggleParticipantPinState(int userId, int screenIndex);
}
}

View File

@@ -0,0 +1,26 @@
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
/// <summary>
/// Describes the ability to mute and unmute a participant's video in a meeting
/// </summary>
public interface IHasParticipantVideoMute : IHasParticipants
{
/// <summary>
/// Mute video of all participants
/// </summary>
/// <param name="userId">The user ID of the participant to mute</param>
void MuteVideoForParticipant(int userId);
/// <summary>
/// Unmute video of all participants
/// </summary>
/// <param name="userId">The user ID of the participant to unmute</param>
void UnmuteVideoForParticipant(int userId);
/// <summary>
/// Toggles video of a participant
/// </summary>
/// <param name="userId">The user ID of the participant to toggle</param>
void ToggleVideoForParticipant(int userId);
}
}

View File

@@ -1,156 +1,31 @@
using System;
using System.Linq;
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
/// <summary>
/// Describes a device that has call participants
/// </summary>
public interface IHasParticipants
{
/// <summary>
/// Gets the collection of participants
/// </summary>
CodecParticipants Participants { get; }
/// <summary>
/// Removes the participant from the meeting
/// </summary>
/// <param name="participant"></param>
void RemoveParticipant(int userId);
/// <summary>
/// Removes the participant from the meeting
/// </summary>
/// <param name="userId"></param>
void RemoveParticipant(int userId);
/// <summary>
/// Sets the participant as the new host
/// </summary>
/// <param name="participant"></param>
void SetParticipantAsHost(int userId);
/// <summary>
/// Sets the participant as the new host
/// </summary>
/// <param name="userId"></param>
void SetParticipantAsHost(int userId);
/// <summary>
/// Admits a participant from the waiting room
/// </summary>
/// <param name="userId"></param>
void AdmitParticipantFromWaitingRoom(int userId);
}
/// <summary>
/// Describes the ability to mute and unmute a participant's video in a meeting
/// </summary>
public interface IHasParticipantVideoMute : IHasParticipants
{
void MuteVideoForParticipant(int userId);
void UnmuteVideoForParticipant(int userId);
void ToggleVideoForParticipant(int userId);
}
/// <summary>
/// Defines the contract for IHasParticipantAudioMute
/// </summary>
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
{
/// <summary>
/// Mute audio of all participants
/// </summary>
void MuteAudioForAllParticipants();
void MuteAudioForParticipant(int userId);
void UnmuteAudioForParticipant(int userId);
void ToggleAudioForParticipant(int userId);
}
/// <summary>
/// Defines the contract for IHasParticipantPinUnpin
/// </summary>
public interface IHasParticipantPinUnpin : IHasParticipants
{
IntFeedback NumberOfScreensFeedback { get; }
int ScreenIndexToPinUserTo { get; }
void PinParticipant(int userId, int screenIndex);
void UnPinParticipant(int userId);
void ToggleParticipantPinState(int userId, int screenIndex);
}
/// <summary>
/// Represents a CodecParticipants
/// </summary>
public class CodecParticipants
{
private List<Participant> _currentParticipants;
public List<Participant> CurrentParticipants
{
get { return _currentParticipants; }
set
{
_currentParticipants = value;
OnParticipantsChanged();
}
}
public Participant Host
{
get
{
return _currentParticipants.FirstOrDefault(p => p.IsHost);
}
}
public event EventHandler<EventArgs> ParticipantsListHasChanged;
public CodecParticipants()
{
_currentParticipants = new List<Participant>();
}
/// <summary>
/// OnParticipantsChanged method
/// </summary>
public void OnParticipantsChanged()
{
var handler = ParticipantsListHasChanged;
if (handler == null) return;
handler(this, new EventArgs());
}
}
/// <summary>
/// Represents a Participant
/// </summary>
public class Participant
{
/// <summary>
/// Gets or sets the UserId
/// </summary>
public int UserId { get; set; }
/// <summary>
/// Gets or sets the IsHost
/// </summary>
public bool IsHost { get; set; }
public bool IsMyself { get; set; }
public string Name { get; set; }
public bool CanMuteVideo { get; set; }
public bool CanUnmuteVideo { get; set; }
public bool VideoMuteFb { get; set; }
public bool AudioMuteFb { get; set; }
/// <summary>
/// Gets or sets the HandIsRaisedFb
/// </summary>
public bool HandIsRaisedFb { get; set; }
/// <summary>
/// Gets or sets the IsPinnedFb
/// </summary>
public bool IsPinnedFb { get; set; }
/// <summary>
/// Gets or sets the ScreenIndexIsPinnedToFb
/// </summary>
public int ScreenIndexIsPinnedToFb { get; set; }
public Participant()
{
// Initialize to -1 (no screen)
ScreenIndexIsPinnedToFb = -1;
}
/// <summary>
/// Admits a participant from the waiting room
/// </summary>
/// <param name="userId"></param>
void AdmitParticipantFromWaitingRoom(int userId);
}
}

View File

@@ -5,10 +5,35 @@
/// </summary>
public interface IHasPresentationOnlyMeeting
{
/// <summary>
/// Starts a presentation only meeting
/// </summary>
void StartSharingOnlyMeeting();
/// <summary>
/// Starts a presentation only meeting with specified display mode
/// </summary>
/// <param name="displayMode">The display mode for the meeting</param>
void StartSharingOnlyMeeting(eSharingMeetingMode displayMode);
/// <summary>
/// Starts a presentation only meeting with specified display mode and duration
/// </summary>
/// <param name="displayMode">The display mode for the meeting</param>
/// <param name="duration">The duration for the meeting</param>
void StartSharingOnlyMeeting(eSharingMeetingMode displayMode, uint duration);
/// <summary>
/// Starts a presentation only meeting with specified display mode, duration, and password
/// </summary>
/// <param name="displayMode">The display mode for the meeting</param>
/// <param name="duration">The duration for the meeting</param>
/// <param name="password">The password for the meeting</param>
void StartSharingOnlyMeeting(eSharingMeetingMode displayMode, uint duration, string password);
/// <summary>
/// Starts a normal meeting from a sharing only meeting
/// </summary>
void StartNormalMeetingFromSharingOnlyMeeting();
}
@@ -17,8 +42,17 @@
/// </summary>
public enum eSharingMeetingMode
{
/// <summary>
/// No specific sharing mode
/// </summary>
None,
/// <summary>
/// Laptop sharing mode
/// </summary>
Laptop,
/// <summary>
/// iOS sharing mode
/// </summary>
Ios,
}
}

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