Compare commits

..

1 Commits

Author SHA1 Message Date
Evan DiLallo
9d122e5391 Merge a583fdb72a into b2f3aa9cfa 2021-03-11 17:26:49 +00:00
64 changed files with 6104 additions and 10139 deletions

View File

@@ -1,27 +0,0 @@
---
name: Request for Information
about: Request specific information about capabilities of the framework
title: "[RFI]-"
labels: RFI
assignees: ''
---
**What is your request?**
Please provide as much detail as possible.
**What is the intended use case**
- [ ] Essentials Standalone Application
- [ ] Essentials + SIMPL Windows Hybrid
**User Interface Requirements**
- [ ] Not Applicable (logic only)
- [ ] Crestron Smart Graphics Touchpanel
- [ ] Cisco Touch10
- [ ] Mobile Control
- [ ] Crestron CH5 Touchpanel interface
**Additional context**
Add any other context or screenshots about the request here.

View File

@@ -36,7 +36,6 @@ namespace PepperDash.Essentials
Thread.MaxNumberOfUserThreads = 400; Thread.MaxNumberOfUserThreads = 400;
Global.ControlSystem = this; Global.ControlSystem = this;
DeviceManager.Initialize(this); DeviceManager.Initialize(this);
SecretsManager.Initialize();
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true; SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
} }
@@ -72,7 +71,7 @@ namespace PepperDash.Essentials
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.AddNewConsoleCommand(s =>
{ {
foreach (var tl in TieLineCollection.Default) foreach (var tl in TieLineCollection.Default)
CrestronConsole.ConsoleCommandResponse(" {0}\r\n", tl); CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
}, },
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator); "listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
@@ -86,8 +85,8 @@ namespace PepperDash.Essentials
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.AddNewConsoleCommand(s =>
{ {
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r\n" + CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
"System URL: {0}\r\n" + "System URL: {0}\r" +
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl); "Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator); }, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);

View File

@@ -137,7 +137,7 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Room\Config\EssentialsDualDisplayRoomPropertiesConfig.cs" /> <Compile Include="Room\Config\EssentialsDualDisplayRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsNDisplayRoomPropertiesConfig.cs" /> <Compile Include="Room\Config\EssentialsNDisplayRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\SimplRoomPropertiesConfig.cs" /> <Compile Include="Room\Config\DDVC01RoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsPresentationPropertiesConfig.cs" /> <Compile Include="Room\Config\EssentialsPresentationPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsHuddleRoomPropertiesConfig.cs" /> <Compile Include="Room\Config\EssentialsHuddleRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs" /> <Compile Include="Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs" />

View File

@@ -8,19 +8,19 @@ using Newtonsoft.Json;
namespace PepperDash.Essentials.Room.Config namespace PepperDash.Essentials.Room.Config
{ {
public class SimplRoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig public class DDVC01RoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig
{ {
[JsonProperty("roomPhoneNumber")] [JsonProperty("roomPhoneNumber")]
public string RoomPhoneNumber { get; set; } public string RoomPhoneNumber { get; set; }
[JsonProperty("roomURI")] [JsonProperty("roomURI")]
public string RoomURI { get; set; } public string RoomURI { get; set; }
[JsonProperty("speedDials")] [JsonProperty("speedDials")]
public List<SimplSpeedDial> SpeedDials { get; set; } public List<DDVC01SpeedDial> SpeedDials { get; set; }
[JsonProperty("volumeSliderNames")] [JsonProperty("volumeSliderNames")]
public List<string> VolumeSliderNames { get; set; } public List<string> VolumeSliderNames { get; set; }
} }
public class SimplSpeedDial public class DDVC01SpeedDial
{ {
[JsonProperty("name")] [JsonProperty("name")]
public string Name { get; set; } public string Name { get; set; }

View File

@@ -196,20 +196,9 @@ namespace PepperDash.Essentials.Room.Config
public string DefaultAudioKey { get; set; } public string DefaultAudioKey { get; set; }
[JsonProperty("sourceListKey")] [JsonProperty("sourceListKey")]
public string SourceListKey { get; set; } public string SourceListKey { get; set; }
[JsonProperty("destinationListKey")]
public string DestinationListKey { get; set; }
[JsonProperty("defaultSourceItem")] [JsonProperty("defaultSourceItem")]
public string DefaultSourceItem { get; set; } public string DefaultSourceItem { get; set; }
/// <summary>
/// Indicates if the room supports advanced sharing
/// </summary>
[JsonProperty("supportsAdvancedSharing")]
public bool SupportsAdvancedSharing { get; set; }
/// <summary>
/// Indicates if non-tech users can change the share mode
/// </summary>
[JsonProperty("userCanChangeShareMode")]
public bool UserCanChangeShareMode { get; set; }
} }
public class EssentialsConferenceRoomPropertiesConfig : EssentialsAvRoomPropertiesConfig public class EssentialsConferenceRoomPropertiesConfig : EssentialsAvRoomPropertiesConfig

View File

@@ -19,8 +19,7 @@ namespace PepperDash.Essentials
{ {
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange, public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange,
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
{ {
private bool _codecExternalSourceChange;
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange; public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
public event SourceInfoChangeHandler CurrentSourceChange; public event SourceInfoChangeHandler CurrentSourceChange;
@@ -179,12 +178,10 @@ namespace PepperDash.Essentials
handler(_CurrentSourceInfo, ChangeType.DidChange); handler(_CurrentSourceInfo, ChangeType.DidChange);
var vc = VideoCodec as IHasExternalSourceSwitching; var vc = VideoCodec as IHasExternalSourceSwitching;
if (vc != null && !_codecExternalSourceChange) if (vc != null)
{ {
vc.SetSelectedSource(CurrentSourceInfoKey); vc.SetSelectedSource(CurrentSourceInfoKey);
} }
_codecExternalSourceChange = false;
} }
} }
SourceListItem _CurrentSourceInfo; SourceListItem _CurrentSourceInfo;
@@ -424,12 +421,6 @@ namespace PepperDash.Essentials
return true; return true;
} }
public void RunRouteActionCodec(string routeKey, string sourceListKey)
{
_codecExternalSourceChange = true;
RunRouteAction(routeKey, sourceListKey);
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -759,7 +750,7 @@ namespace PepperDash.Essentials
x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort; x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort;
videoCodecWithExternalSwitching.ClearExternalSources(); videoCodecWithExternalSwitching.ClearExternalSources();
videoCodecWithExternalSwitching.RunRouteAction = RunRouteActionCodec; videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction;
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ; var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
foreach (var kvp in srcList) foreach (var kvp in srcList)

View File

@@ -107,18 +107,14 @@ namespace PepperDash.Essentials
private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel) private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
{ {
//Debug.Console(2, this, "TunerPresetsOnPresetRecalled");
if (!_currentPresets.ContainsKey(device.Key)) if (!_currentPresets.ContainsKey(device.Key))
{ {
return; return;
} }
//Debug.Console(2, this, "Tuner Key: {0} Channel: {1}", device.Key, channel);
_currentPresets[device.Key] = channel; _currentPresets[device.Key] = channel;
if (CurrentPresetsFeedbacks.ContainsKey(device.Key)) if (!CurrentPresetsFeedbacks.ContainsKey(device.Key))
{ {
CurrentPresetsFeedbacks[device.Key].FireUpdate(); CurrentPresetsFeedbacks[device.Key].FireUpdate();
} }
@@ -187,12 +183,11 @@ namespace PepperDash.Essentials
var roomEvent = _roomScheduledEventGroup.ScheduledEvents[scheduledEvent.Key]; var roomEvent = _roomScheduledEventGroup.ScheduledEvents[scheduledEvent.Key];
//if (SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) && if (!SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) &&
// SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days)) !SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days))
//{ {
// Debug.Console(1, this, "Existing event matches new event properties. Nothing to update"); return;
// return; }
//}
Debug.Console(1, this, Debug.Console(1, this,
"Existing event does not match new config properties. Deleting existing event '{0}' and creating new event from configuration", "Existing event does not match new config properties. Deleting existing event '{0}' and creating new event from configuration",

View File

@@ -146,139 +146,16 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
/// ///
/// </summary> /// </summary>
[Obsolete("use PepperDash.Essentials.Core.Bridges.JoinMaps version")] [Obsolete("use PepperDash.Essentials.Core.Bridges.JoinMaps version")]
public class GlsPartitionSensorJoinMap:JoinMapBaseAdvanced public class GlsPartitionSensorJoinMap : PepperDash.Essentials.Core.Bridges.JoinMaps.GlsPartitionSensorJoinMap
{ {
[JoinName("IsOnline")]
public JoinDataComplete IsOnline = new JoinDataComplete(
new JoinData
{
JoinNumber = 1,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Is Online",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(
new JoinData
{
JoinNumber = 1,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Name",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("Enable")]
public JoinDataComplete Enable = new JoinDataComplete(
new JoinData
{
JoinNumber = 2,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Enable",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("PartitionSensed")]
public JoinDataComplete PartitionSensed = new JoinDataComplete(
new JoinData
{
JoinNumber = 3,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Partition Sensed",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("PartitionNotSensed")]
public JoinDataComplete PartitionNotSensed = new JoinDataComplete(
new JoinData
{
JoinNumber = 4,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Partition Not Sensed",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("IncreaseSensitivity")]
public JoinDataComplete IncreaseSensitivity = new JoinDataComplete(
new JoinData
{
JoinNumber = 6,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Increase Sensitivity",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DecreaseSensitivity")]
public JoinDataComplete DecreaseSensitivity = new JoinDataComplete(
new JoinData
{
JoinNumber = 7,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Decrease Sensitivity",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("Sensitivity")]
public JoinDataComplete Sensitivity = new JoinDataComplete(
new JoinData
{
JoinNumber = 2,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Sensitivity",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Analog
});
/// <summary>
/// Constructor to use when instantiating this Join Map without inheriting from it
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
public GlsPartitionSensorJoinMap(uint joinStart) public GlsPartitionSensorJoinMap(uint joinStart)
: this(joinStart, typeof(GlsPartitionSensorJoinMap)) : this(joinStart, typeof(GlsPartitionSensorJoinMap))
{ {
} }
/// <summary> protected GlsPartitionSensorJoinMap(uint joinStart, Type type) : base(joinStart, type)
/// Constructor to use when extending this Join map
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
/// <param name="type">Type of the child join map</param>
protected GlsPartitionSensorJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{ {
} }
} }
} }

View File

@@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core
{ {
Communication = comm; Communication = comm;
PortGather = new CommunicationGather(Communication, '\x0d'); PortGather = new CommunicationGather(Communication, '\x0d');
//PortGather.LineReceived += this.Port_LineReceived; PortGather.LineReceived += this.Port_LineReceived;
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties); CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
LineEnding = props.LineEnding; LineEnding = props.LineEnding;
} }
@@ -47,6 +47,13 @@ namespace PepperDash.Essentials.Core
return true; return true;
} }
void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
{
if (Debug.Level == 2)
Debug.Console(2, this, "RX: '{0}'",
ShowHexResponse ? ComTextHelper.GetEscapedText(args.Text) : args.Text);
}
void SendLine(string s) void SendLine(string s)
{ {
//if (Debug.Level == 2) //if (Debug.Level == 2)

View File

@@ -25,7 +25,6 @@ namespace PepperDash.Essentials.Core
public GenericComm(DeviceConfig config) public GenericComm(DeviceConfig config)
: base(config) : base(config)
{ {
PropertiesConfig = CommFactory.GetControlPropertiesConfig(config); PropertiesConfig = CommFactory.GetControlPropertiesConfig(config);
var commPort = CommFactory.CreateCommForDevice(config); var commPort = CommFactory.CreateCommForDevice(config);
@@ -97,6 +96,7 @@ namespace PepperDash.Essentials.Core
// this is a permanent event handler. This cannot be -= from event // this is a permanent event handler. This cannot be -= from event
CommPort.TextReceived += (s, a) => CommPort.TextReceived += (s, a) =>
{ {
Debug.Console(2, this, "RX: {0}", a.Text);
trilist.SetString(joinMap.TextReceived.JoinNumber, a.Text); trilist.SetString(joinMap.TextReceived.JoinNumber, a.Text);
}; };
trilist.SetStringSigAction(joinMap.SendText.JoinNumber, s => CommPort.SendText(s)); trilist.SetStringSigAction(joinMap.SendText.JoinNumber, s => CommPort.SendText(s));

View File

@@ -33,6 +33,7 @@ namespace PepperDash.Essentials.Core
string url = string.Format("http://{0}/{1}", Client.HostName, path); string url = string.Format("http://{0}/{1}", Client.HostName, path);
request.Url = new UrlParser(url); request.Url = new UrlParser(url);
HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request); HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request);
Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url);
} }
public void SendText(string format, params object[] items) public void SendText(string format, params object[] items)
{ {
@@ -40,6 +41,7 @@ namespace PepperDash.Essentials.Core
string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items)); string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
request.Url = new UrlParser(url); request.Url = new UrlParser(url);
HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request); HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request);
Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url);
} }
public void SendTextNoResponse(string format, params object[] items) public void SendTextNoResponse(string format, params object[] items)
@@ -48,6 +50,7 @@ namespace PepperDash.Essentials.Core
string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items)); string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
request.Url = new UrlParser(url); request.Url = new UrlParser(url);
Client.Dispatch(request); Client.Dispatch(request);
Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url);
} }
private void Response(HttpClientResponse response, HTTP_CALLBACK_ERROR error, object request) private void Response(HttpClientResponse response, HTTP_CALLBACK_ERROR error, object request)
@@ -60,6 +63,10 @@ namespace PepperDash.Essentials.Core
{ {
if (ResponseRecived != null) if (ResponseRecived != null)
ResponseRecived(this, new GenericHttpClientEventArgs(responseReceived.ContentString, (request as HttpClientRequest).Url.ToString(), error)); ResponseRecived(this, new GenericHttpClientEventArgs(responseReceived.ContentString, (request as HttpClientRequest).Url.ToString(), error));
Debug.Console(2, this, "GenericHttpClient ResponseReceived");
Debug.Console(2, this, "RX:{0}", responseReceived.ContentString);
Debug.Console(2, this, "TX:{0}", (request as HttpClientRequest).Url.ToString());
} }
} }

View File

@@ -1,6 +1,11 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@@ -20,25 +25,12 @@ namespace PepperDash.Essentials.Core.Config
[JsonProperty("sourceLists")] [JsonProperty("sourceLists")]
public Dictionary<string, Dictionary<string, SourceListItem>> SourceLists { get; set; } public Dictionary<string, Dictionary<string, SourceListItem>> SourceLists { get; set; }
[JsonProperty("destinationLists")] [JsonProperty("tieLines")]
public Dictionary<string, Dictionary<string,DestinationListItem>> DestinationLists { get; set; }
[JsonProperty("tieLines")]
public List<TieLineConfig> TieLines { get; set; } public List<TieLineConfig> TieLines { get; set; }
[JsonProperty("joinMaps")] [JsonProperty("joinMaps")]
public Dictionary<string, JObject> JoinMaps { get; set; } public Dictionary<string, JObject> JoinMaps { get; set; }
public BasicConfig()
{
Info = new InfoConfig();
Devices = new List<DeviceConfig>();
SourceLists = new Dictionary<string, Dictionary<string, SourceListItem>>();
DestinationLists = new Dictionary<string, Dictionary<string, DestinationListItem>>();
TieLines = new List<TieLineConfig>();
JoinMaps = new Dictionary<string, JObject>();
}
/// <summary> /// <summary>
/// Checks SourceLists for a given list and returns it if found. Otherwise, returns null /// Checks SourceLists for a given list and returns it if found. Otherwise, returns null
/// </summary> /// </summary>
@@ -50,21 +42,6 @@ namespace PepperDash.Essentials.Core.Config
return SourceLists[key]; return SourceLists[key];
} }
/// <summary>
/// Retrieves a DestinationListItem based on the key
/// </summary>
/// <param name="key">key of the item to retrieve</param>
/// <returns>DestinationListItem if the key exists, null otherwise</returns>
public Dictionary<string, DestinationListItem> GetDestinationListForKey(string key)
{
if (string.IsNullOrEmpty(key) || !DestinationLists.ContainsKey(key))
{
return null;
}
return DestinationLists[key];
}
/// <summary> /// <summary>
/// Checks Devices for an item with a Key that matches and returns it if found. Otherwise, retunes null /// Checks Devices for an item with a Key that matches and returns it if found. Otherwise, retunes null
/// </summary> /// </summary>

View File

@@ -30,19 +30,7 @@ namespace PepperDash.Essentials.Core.Config
[JsonProperty("properties")] [JsonProperty("properties")]
[JsonConverter(typeof(DevicePropertiesConverter))] [JsonConverter(typeof(DevicePropertiesConverter))]
public JToken Properties { get; set; } public JToken Properties { get; set; }
public DeviceConfig(DeviceConfig dc)
{
Key = dc.Key;
Uid = dc.Uid;
Name = dc.Name;
Group = dc.Group;
Type = dc.Type;
Properties = JToken.FromObject(dc.Properties);
}
public DeviceConfig() {}
} }
/// <summary> /// <summary>

View File

@@ -1,162 +1,162 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
namespace PepperDash.Essentials.Core.Config namespace PepperDash.Essentials.Core.Config
{ {
/// <summary> /// <summary>
/// Responsible for updating config at runtime, and writing the updates out to a local file /// Responsible for updating config at runtime, and writing the updates out to a local file
/// </summary> /// </summary>
public class ConfigWriter public class ConfigWriter
{ {
public const string LocalConfigFolder = "LocalConfig"; public const string LocalConfigFolder = "LocalConfig";
public const long WriteTimeout = 30000; public const long WriteTimeout = 30000;
public static CTimer WriteTimer; public static CTimer WriteTimer;
static CCriticalSection fileLock = new CCriticalSection(); static CCriticalSection fileLock = new CCriticalSection();
/// <summary> /// <summary>
/// Updates the config properties of a device /// Updates the config properties of a device
/// </summary> /// </summary>
/// <param name="deviceKey"></param> /// <param name="deviceKey"></param>
/// <param name="properties"></param> /// <param name="properties"></param>
/// <returns></returns> /// <returns></returns>
public static bool UpdateDeviceProperties(string deviceKey, JToken properties) public static bool UpdateDeviceProperties(string deviceKey, JToken properties)
{ {
bool success = false; bool success = false;
// Get the current device config // Get the current device config
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey)); var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey));
if (deviceConfig != null) if (deviceConfig != null)
{ {
// Replace the current properties JToken with the new one passed into this method // Replace the current properties JToken with the new one passed into this method
deviceConfig.Properties = properties; deviceConfig.Properties = properties;
Debug.Console(1, "Updated properties of device: '{0}'", deviceKey); Debug.Console(1, "Updated properties of device: '{0}'", deviceKey);
success = true; success = true;
} }
ResetTimer(); ResetTimer();
return success; return success;
} }
public static bool UpdateDeviceConfig(DeviceConfig config) public static bool UpdateDeviceConfig(DeviceConfig config)
{ {
bool success = false; bool success = false;
var deviceConfigIndex = ConfigReader.ConfigObject.Devices.FindIndex(d => d.Key.Equals(config.Key)); var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(config.Key));
if (deviceConfigIndex >= 0) if (deviceConfig != null)
{ {
ConfigReader.ConfigObject.Devices[deviceConfigIndex] = config; deviceConfig = config;
Debug.Console(1, "Updated config of device: '{0}'", config.Key); Debug.Console(1, "Updated config of device: '{0}'", config.Key);
success = true; success = true;
} }
ResetTimer(); ResetTimer();
return success; return success;
} }
public static bool UpdateRoomConfig(DeviceConfig config) public static bool UpdateRoomConfig(DeviceConfig config)
{ {
bool success = false; bool success = false;
var roomConfigIndex = ConfigReader.ConfigObject.Rooms.FindIndex(d => d.Key.Equals(config.Key)); var deviceConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(d => d.Key.Equals(config.Key));
if (roomConfigIndex >= 0) if (deviceConfig != null)
{ {
ConfigReader.ConfigObject.Rooms[roomConfigIndex] = config; deviceConfig = config;
Debug.Console(1, "Updated room of device: '{0}'", config.Key); Debug.Console(1, "Updated config of device: '{0}'", config.Key);
success = true; success = true;
} }
ResetTimer(); ResetTimer();
return success; return success;
} }
/// <summary> /// <summary>
/// Resets (or starts) the write timer /// Resets (or starts) the write timer
/// </summary> /// </summary>
static void ResetTimer() static void ResetTimer()
{ {
if (WriteTimer == null) if (WriteTimer == null)
WriteTimer = new CTimer(WriteConfigFile, WriteTimeout); WriteTimer = new CTimer(WriteConfigFile, WriteTimeout);
WriteTimer.Reset(WriteTimeout); WriteTimer.Reset(WriteTimeout);
Debug.Console(1, "Config File write timer has been reset."); Debug.Console(1, "Config File write timer has been reset.");
} }
/// <summary> /// <summary>
/// Writes the current config to a file in the LocalConfig subfolder /// Writes the current config to a file in the LocalConfig subfolder
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private static void WriteConfigFile(object o) private static void WriteConfigFile(object o)
{ {
var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json"; var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json";
var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject); var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject);
WriteFile(filePath, configData); WriteFile(filePath, configData);
} }
/// <summary> /// <summary>
/// Writes /// Writes
/// </summary> /// </summary>
/// <param name="filepath"></param> /// <param name="filepath"></param>
/// <param name="o"></param> /// <param name="o"></param>
public static void WriteFile(string filePath, string configData) public static void WriteFile(string filePath, string configData)
{ {
if (WriteTimer != null) if (WriteTimer != null)
WriteTimer.Stop(); WriteTimer.Stop();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file"); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
try try
{ {
if (fileLock.TryEnter()) if (fileLock.TryEnter())
{ {
using (StreamWriter sw = new StreamWriter(filePath)) using (StreamWriter sw = new StreamWriter(filePath))
{ {
sw.Write(configData); sw.Write(configData);
sw.Flush(); sw.Flush();
} }
} }
else else
{ {
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock"); Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock");
} }
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e); Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e);
} }
finally finally
{ {
if (fileLock != null && !fileLock.Disposed) if (fileLock != null && !fileLock.Disposed)
fileLock.Leave(); fileLock.Leave();
} }
} }
} }
} }

View File

@@ -51,13 +51,6 @@ namespace PepperDash.Essentials.Core.Config
[JsonProperty("rooms")] [JsonProperty("rooms")]
public List<DeviceConfig> Rooms { get; set; } public List<DeviceConfig> Rooms { get; set; }
public EssentialsConfig()
: base()
{
Rooms = new List<DeviceConfig>();
}
} }
/// <summary> /// <summary>

View File

@@ -12,9 +12,8 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{ {
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
public interface IHasBranding public interface IHasBranding:PepperDash.Essentials.Core.DeviceTypeInterfaces.IHasBranding
{ {
bool BrandingEnabled { get; }
void InitializeBranding(string roomKey);
} }
} }

View File

@@ -1,5 +1,4 @@
using System; using System;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{ {
@@ -17,13 +16,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{ {
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
public interface IHasPhoneDialing public interface IHasPhoneDialing:PepperDash.Essentials.Core.DeviceTypeInterfaces.IHasPhoneDialing
{ {
BoolFeedback PhoneOffHookFeedback { get; }
StringFeedback CallerIdNameFeedback { get; }
StringFeedback CallerIdNumberFeedback { get; }
void DialPhoneCall(string number);
void EndPhoneCall();
void SendDtmfToPhone(string digit);
} }
} }

View File

@@ -20,16 +20,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{ {
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
public interface ILanguageDefinition public interface ILanguageDefinition:PepperDash.Essentials.Core.DeviceTypeInterfaces.ILanguageDefinition
{ {
string LocaleName { get; set; }
string FriendlyName { get; set; }
bool Enable { get; set; }
List<LanguageLabel> UiLabels { get; set; }
List<LanguageLabel> Sources { get; set; }
List<LanguageLabel> Destinations { get; set; }
List<LanguageLabel> SourceGroupNames { get; set; }
List<LanguageLabel> DestinationGroupNames { get; set; }
List<LanguageLabel> RoomNames { get; set; }
} }
} }

View File

@@ -15,11 +15,8 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{ {
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
public interface ILanguageProvider public interface ILanguageProvider:PepperDash.Essentials.Core.DeviceTypeInterfaces.ILanguageProvider
{ {
ILanguageDefinition CurrentLanguage { get; set; }
event EventHandler CurrentLanguageChanged;
} }
} }

View File

@@ -20,10 +20,6 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{ {
event EventHandler<EventArgs> UserCodeChanged; event EventHandler<EventArgs> UserCodeChanged;
event EventHandler<EventArgs> UserPromptedForCode;
event EventHandler<EventArgs> ClientJoined;
string UserCode { get; } string UserCode { get; }
string QrCodeUrl { get; } string QrCodeUrl { get; }

View File

@@ -15,11 +15,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{ {
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
public class LanguageLabel public class LanguageLabel: PepperDash.Essentials.Core.DeviceTypeInterfaces.LanguageLabel
{ {
public string Key { get; set; }
public string Description { get; set; }
public string DisplayText { get; set; }
public uint JoinNumber { get; set; }
} }
} }

View File

@@ -1,54 +0,0 @@
using Newtonsoft.Json;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core
{
public class DestinationListItem
{
[JsonProperty("sinkKey")]
public string SinkKey { get; set; }
private EssentialsDevice _sinkDevice;
[JsonIgnore]
public EssentialsDevice SinkDevice
{
get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as EssentialsDevice); }
}
[JsonProperty("preferredName")]
public string PreferredName
{
get
{
if (!string.IsNullOrEmpty(Name))
{
return Name;
}
return SinkDevice == null ? "---" : SinkDevice.Name;
}
}
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("includeInDestinationList")]
public bool IncludeInDestinationList { get; set; }
[JsonProperty("order")]
public int Order { get; set; }
[JsonProperty("surfaceLocation")]
public int SurfaceLocation { get; set; }
[JsonProperty("verticalLocation")]
public int VerticalLocation { get; set; }
[JsonProperty("horizontalLocation")]
public int HorizontalLocation { get; set; }
[JsonProperty("sinkType")]
public eRoutingSignalType SinkType { get; set; }
}
}

View File

@@ -20,23 +20,8 @@ namespace PepperDash.Essentials.Core
/// <param name="json"></param> /// <param name="json"></param>
public static void DoDeviceActionWithJson(string json) public static void DoDeviceActionWithJson(string json)
{ {
if (String.IsNullOrEmpty(json)) var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
{ DoDeviceAction(action);
CrestronConsole.ConsoleCommandResponse(
"Please provide a JSON object matching the format {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}.\r\nIf the method has no parameters, the \"params\" object may be omitted.");
return;
}
try
{
var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
DoDeviceAction(action);
}
catch (Exception ex)
{
CrestronConsole.ConsoleCommandResponse("Incorrect format for JSON. Please check that the format matches {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}");
}
} }
@@ -48,65 +33,31 @@ namespace PepperDash.Essentials.Core
{ {
var key = action.DeviceKey; var key = action.DeviceKey;
var obj = FindObjectOnPath(key); var obj = FindObjectOnPath(key);
if (obj == null) if (obj == null)
{ return;
CrestronConsole.ConsoleCommandResponse("Unable to find object at path {0}", key);
return;
}
if (action.Params == null) CType t = obj.GetType();
{ var method = t.GetMethod(action.MethodName);
//no params, so setting action.Params to empty array if (method == null)
action.Params = new object[0]; {
} Debug.Console(0, "Method '{0}' not found", action.MethodName);
return;
CType t = obj.GetType(); }
try var mParams = method.GetParameters();
{ // Add empty params if not provided
var methods = t.GetMethods().Where(m => m.Name == action.MethodName).ToList(); if (action.Params == null) action.Params = new object[0];
if (mParams.Length > action.Params.Length)
var method = methods.Count == 1 ? methods[0] : methods.FirstOrDefault(m => m.GetParameters().Length == action.Params.Length); {
Debug.Console(0, "Method '{0}' requires {1} params", action.MethodName, mParams.Length);
if (method == null) return;
{ }
CrestronConsole.ConsoleCommandResponse( object[] convertedParams = mParams
"Unable to find method with name {0} and that matches parameters {1}", action.MethodName, .Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType,
action.Params); System.Globalization.CultureInfo.InvariantCulture))
return; .ToArray();
} object ret = method.Invoke(obj, convertedParams);
var mParams = method.GetParameters();
var convertedParams = mParams
.Select((p, i) => ConvertType(action.Params[i], p.ParameterType))
.ToArray();
method.Invoke(obj, convertedParams);
CrestronConsole.ConsoleCommandResponse("Method {0} successfully called on device {1}", method.Name,
action.DeviceKey);
}
catch (Exception ex)
{
CrestronConsole.ConsoleCommandResponse("Unable to call method with name {0}. {1}", action.MethodName,
ex.Message);}
} }
private static object ConvertType(object value, Type conversionType)
{
if (!conversionType.IsEnum)
{
return Convert.ChangeType(value, conversionType, System.Globalization.CultureInfo.InvariantCulture);
}
var stringValue = Convert.ToString(value);
if (String.IsNullOrEmpty(stringValue))
{
throw new InvalidCastException(
String.Format("{0} cannot be converted to a string prior to conversion to enum"));
}
return Enum.Parse(conversionType, stringValue, true);
}
/// <summary> /// <summary>
/// Gets the properties on a device /// Gets the properties on a device
/// </summary> /// </summary>
@@ -291,8 +242,6 @@ namespace PepperDash.Essentials.Core
//var props = t.GetProperties().Select(p => new PropertyNameType(p, obj)); //var props = t.GetProperties().Select(p => new PropertyNameType(p, obj));
//return JsonConvert.SerializeObject(props, Formatting.Indented); //return JsonConvert.SerializeObject(props, Formatting.Indented);
} }
} }
public class DeviceActionWrapper public class DeviceActionWrapper

View File

@@ -46,7 +46,7 @@ namespace PepperDash.Essentials.Core
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive", CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator); "Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(SetDeviceStreamDebugging, "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(s => SetDeviceStreamDebugging(s), "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator);
} }
@@ -387,15 +387,6 @@ namespace PepperDash.Essentials.Core
/// <param name="s"></param> /// <param name="s"></param>
public static void SetDeviceStreamDebugging(string s) public static void SetDeviceStreamDebugging(string s)
{ {
if (String.IsNullOrEmpty(s) || s.Contains("?"))
{
CrestronConsole.ConsoleCommandResponse(
@"SETDEVICESTREAMDEBUG [{deviceKey}] [OFF |TX | RX | BOTH] [timeOutInMinutes]
{deviceKey} [OFF | TX | RX | BOTH] - Device to set stream debugging on, and which setting to use
timeOutInMinutes - Set timeout for stream debugging. Default is 30 minutes");
return;
}
var args = s.Split(' '); var args = s.Split(' ');
var deviceKey = args[0]; var deviceKey = args[0];
@@ -446,7 +437,7 @@ namespace PepperDash.Essentials.Core
else else
{ {
device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting); device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
Debug.Console(0, "Device: '{0}' debug level set to {1} for default time (30 minutes)", deviceKey, debugSetting); Debug.Console(0, "Device: '{0}' debug level set to {1) for default time (30 minutes)", deviceKey, debugSetting);
} }
} }

View File

@@ -7,8 +7,6 @@ using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Essentials.Core.Devices namespace PepperDash.Essentials.Core.Devices
{ {
@@ -54,8 +52,6 @@ namespace PepperDash.Essentials.Core.Devices
Name = config.Name; Name = config.Name;
} }
/// <summary> /// <summary>
/// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc) /// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc)
/// </summary> /// </summary>

View File

@@ -130,24 +130,10 @@ namespace PepperDash.Essentials.Core
[JsonProperty("sourceListKey")] [JsonProperty("sourceListKey")]
public string SourceListKey { get; set; } public string SourceListKey { get; set; }
/// <summary>
/// Indicates if the device associated with this source is controllable
/// </summary>
[JsonProperty("isControllable")]
public bool IsControllable { get; set; }
/// <summary>
/// Indicates that the device associated with this source has audio available
/// </summary>
[JsonProperty("isAudioSource")]
public bool IsAudioSource { get; set; }
public SourceListItem() public SourceListItem()
{ {
Icon = "Blank"; Icon = "Blank";
} }
} }
public class SourceRouteListItem public class SourceRouteListItem

View File

@@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Essentials.Core
{
public static class JsonExtensions
{
public static List<JToken> FindTokens(this JToken containerToken, string name)
{
List<JToken> matches = new List<JToken>();
FindTokens(containerToken, name, matches);
return matches;
}
private static void FindTokens(JToken containerToken, string name, List<JToken> matches)
{
if (containerToken.Type == JTokenType.Object)
{
foreach (JProperty child in containerToken.Children<JProperty>())
{
if (child.Name == name)
{
matches.Add(child.Value);
}
FindTokens(child.Value, name, matches);
}
}
else if (containerToken.Type == JTokenType.Array)
{
foreach (JToken child in containerToken.Children())
{
FindTokens(child, name, matches);
}
}
}
}
}

View File

@@ -7,8 +7,6 @@ using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO; using Crestron.SimplSharpPro.GeneralIO;
using Crestron.SimplSharp.Reflection; using Crestron.SimplSharp.Reflection;
using PepperDash.Core; using PepperDash.Core;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.CrestronIO; using PepperDash.Essentials.Core.CrestronIO;
@@ -85,81 +83,33 @@ namespace PepperDash.Essentials.Core
var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method }; var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method };
DeviceFactory.FactoryMethods.Add(typeName, wrapper); DeviceFactory.FactoryMethods.Add(typeName, wrapper);
} }
private static void CheckForSecrets(IEnumerable<JProperty> obj) /// <summary>
{ /// The factory method for Core "things". Also iterates the Factory methods that have
foreach (var prop in obj.Where(prop => prop.Value as JObject != null)) /// been loaded from plugins
{ /// </summary>
if (prop.Name.ToLower() == "secret") /// <param name="dc"></param>
{ /// <returns></returns>
var secret = GetSecret(prop.Children().First().ToObject<SecretsPropertiesConfig>()); public static IKeyed GetDevice(DeviceConfig dc)
//var secret = GetSecret(JsonConvert.DeserializeObject<SecretsPropertiesConfig>(prop.Children().First().ToString())); {
prop.Parent.Replace(secret); var key = dc.Key;
} var name = dc.Name;
var recurseProp = prop.Value as JObject; var type = dc.Type;
if (recurseProp == null) return; var properties = dc.Properties;
CheckForSecrets(recurseProp.Properties());
} var typeName = dc.Type.ToLower();
}
// Check for types that have been added by plugin dlls.
private static string GetSecret(SecretsPropertiesConfig data) if (FactoryMethods.ContainsKey(typeName))
{ {
var secretProvider = SecretsManager.GetSecretProviderByKey(data.Provider); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
if (secretProvider == null) return null; return FactoryMethods[typeName].FactoryMethod(dc);
var secret = secretProvider.GetSecret(data.Key); }
if (secret != null) return (string) secret.Value;
Debug.Console(1, return null;
"Unable to retrieve secret {0}{1} - Make sure you've added it to the secrets provider", }
data.Provider, data.Key);
return String.Empty;
}
/// <summary>
/// The factory method for Core "things". Also iterates the Factory methods that have
/// been loaded from plugins
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public static IKeyed GetDevice(DeviceConfig dc)
{
try
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
var localDc = new DeviceConfig(dc);
var key = localDc.Key;
var name = localDc.Name;
var type = localDc.Type;
var properties = localDc.Properties;
//var propRecurse = properties;
var typeName = localDc.Type.ToLower();
var jObject = properties as JObject;
if (jObject != null)
{
var jProp = jObject.Properties();
CheckForSecrets(jProp);
}
Debug.Console(2, "typeName = {0}", typeName);
// Check for types that have been added by plugin dlls.
return !FactoryMethods.ContainsKey(typeName) ? null : FactoryMethods[typeName].FactoryMethod(localDc);
}
catch (Exception ex)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message);
Debug.Console(2, "{0}", ex.StackTrace);
return null;
}
}
/// <summary> /// <summary>
/// Prints the type names and associated metadata from the FactoryMethods collection. /// Prints the type names and associated metadata from the FactoryMethods collection.
/// </summary> /// </summary>

View File

@@ -27,20 +27,15 @@ namespace PepperDash.Essentials.Core
namespace PepperDash_Essentials_Core namespace PepperDash_Essentials_Core
{ {
[Obsolete("Use PepperDash.Essentials.Core")] [Obsolete("Use PepperDash.Essentials.Core")]
public class IsReadyEventArgs : EventArgs public class IsReadyEventArgs : PepperDash.Essentials.Core.IsReadyEventArgs
{ {
public bool IsReady { get; set; } public IsReadyEventArgs(bool data) : base(data)
public IsReadyEventArgs(bool data)
{ {
IsReady = data;
} }
} }
[Obsolete("Use PepperDash.Essentials.Core")] [Obsolete("Use PepperDash.Essentials.Core")]
public interface IHasReady public interface IHasReady: PepperDash.Essentials.Core.IHasReady
{ {
event EventHandler<IsReadyEventArgs> IsReadyEvent;
bool IsReady { get; }
} }
} }

View File

@@ -24,10 +24,6 @@ namespace PepperDash.Essentials.Core
CrestronConsole.AddNewConsoleCommand(ClearEventsFromGroup, "ClearAllEvents", "Clears all scheduled events for this group", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(ClearEventsFromGroup, "ClearAllEvents", "Clears all scheduled events for this group", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListAllEventGroups, "ListAllEventGroups", "Lists all the event groups by key", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(ListAllEventGroups, "ListAllEventGroups", "Lists all the event groups by key", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListAllEventsForGroup, "ListEventsForGroup",
"Lists all events for the given group", ConsoleAccessLevelEnum.AccessOperator);
} }
/// <summary> /// <summary>
@@ -36,26 +32,12 @@ namespace PepperDash.Essentials.Core
/// <param name="groupName"></param> /// <param name="groupName"></param>
static void ClearEventsFromGroup(string groupName) static void ClearEventsFromGroup(string groupName)
{ {
if (!EventGroups.ContainsKey(groupName))
{
Debug.Console(0,
"[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.",
groupName);
return;
}
var group = EventGroups[groupName]; var group = EventGroups[groupName];
if (group != null) if (group != null)
{
group.ClearAllEvents(); group.ClearAllEvents();
Debug.Console(0, "[Scheduler]: All events deleted from group '{0}'", groupName);
}
else else
Debug.Console(0, Debug.Console(0, "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", groupName);
"[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.",
groupName);
} }
static void ListAllEventGroups(string command) static void ListAllEventGroups(string command)
@@ -67,33 +49,6 @@ namespace PepperDash.Essentials.Core
} }
} }
static void ListAllEventsForGroup(string args)
{
Debug.Console(0, "Getting events for group {0}...", args);
ScheduledEventGroup group;
if (!EventGroups.TryGetValue(args, out group))
{
Debug.Console(0, "Unabled to get event group for key {0}", args);
return;
}
foreach (var evt in group.ScheduledEvents)
{
Debug.Console(0,
@"
****Event key {0}****
Event date/time: {1}
Persistent: {2}
Acknowlegable: {3}
Recurrence: {4}
Recurrence Days: {5}
********************", evt.Key, evt.Value.DateAndTime, evt.Value.Persistent, evt.Value.Acknowledgeable,
evt.Value.Recurrence.Recurrence, evt.Value.Recurrence.RecurrenceDays);
}
}
/// <summary> /// <summary>
/// Adds the event group to the global list /// Adds the event group to the global list
/// </summary> /// </summary>

View File

@@ -48,39 +48,39 @@
<ItemGroup> <ItemGroup>
<Reference Include="Crestron.SimplSharpPro.DeviceSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.DeviceSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.DM, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.DM, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.EthernetCommunications, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.EthernetCommunications, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.EthernetCommunications.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.EthernetCommunications.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.Fusion, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.Fusion, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.Gateways, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.Gateways, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.GeneralIO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.GeneralIO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.Remotes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.Remotes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Remotes.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Remotes.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.ThreeSeriesCards, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.ThreeSeriesCards, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.ThreeSeriesCards.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.ThreeSeriesCards.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
</Reference> </Reference>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
<Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
@@ -89,30 +89,30 @@
</Reference> </Reference>
<Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="SimplSharpHelperInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpHelperInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="SimplSharpNewtonsoft, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpNewtonsoft, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll</HintPath>
</Reference> </Reference>
<Reference Include="SimplSharpPro, Version=1.5.3.17, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpPro, Version=1.5.3.17, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="SimplSharpReflectionInterface, Version=1.0.5583.25238, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpReflectionInterface, Version=1.0.5583.25238, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath>
</Reference> </Reference>
<Reference Include="SimplSharpTimerEventInterface, Version=1.0.6197.20052, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpTimerEventInterface, Version=1.0.6197.20052, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpTimerEventInterface.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpTimerEventInterface.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@@ -189,7 +189,6 @@
<Compile Include="Device Info\IDeviceInfoProvider.cs" /> <Compile Include="Device Info\IDeviceInfoProvider.cs" />
<Compile Include="Devices\CodecInterfaces.cs" /> <Compile Include="Devices\CodecInterfaces.cs" />
<Compile Include="Devices\CrestronProcessor.cs" /> <Compile Include="Devices\CrestronProcessor.cs" />
<Compile Include="Devices\DestinationListItem.cs" />
<Compile Include="Devices\DeviceApiBase.cs" /> <Compile Include="Devices\DeviceApiBase.cs" />
<Compile Include="Devices\DeviceFeedbackExtensions.cs" /> <Compile Include="Devices\DeviceFeedbackExtensions.cs" />
<Compile Include="Devices\EssentialsBridgeableDevice.cs" /> <Compile Include="Devices\EssentialsBridgeableDevice.cs" />
@@ -209,7 +208,6 @@
<Compile Include="DeviceTypeInterfaces\IHasFarEndContentStatus.cs" /> <Compile Include="DeviceTypeInterfaces\IHasFarEndContentStatus.cs" />
<Compile Include="DeviceTypeInterfaces\IHasPhoneDialing.cs" /> <Compile Include="DeviceTypeInterfaces\IHasPhoneDialing.cs" />
<Compile Include="DeviceTypeInterfaces\IMobileControl.cs" /> <Compile Include="DeviceTypeInterfaces\IMobileControl.cs" />
<Compile Include="Extensions\JsonExtensions.cs" />
<Compile Include="Factory\DeviceFactory.cs" /> <Compile Include="Factory\DeviceFactory.cs" />
<Compile Include="Factory\IDeviceFactory.cs" /> <Compile Include="Factory\IDeviceFactory.cs" />
<Compile Include="Factory\ReadyEventArgs.cs" /> <Compile Include="Factory\ReadyEventArgs.cs" />
@@ -321,10 +319,6 @@
<Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" /> <Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" />
<Compile Include="Routing\RoutingPortNames.cs" /> <Compile Include="Routing\RoutingPortNames.cs" />
<Compile Include="Routing\TieLineConfig.cs" /> <Compile Include="Routing\TieLineConfig.cs" />
<Compile Include="Secrets\CrestronSecretsProvider.cs" />
<Compile Include="Secrets\Interfaces.cs" />
<Compile Include="Secrets\SecretsManager.cs" />
<Compile Include="Secrets\SecretsPropertiesConfig.cs" />
<Compile Include="Shades\Shade Interfaces.cs" /> <Compile Include="Shades\Shade Interfaces.cs" />
<Compile Include="Shades\ShadeBase.cs" /> <Compile Include="Shades\ShadeBase.cs" />
<Compile Include="Shades\ShadeController.cs" /> <Compile Include="Shades\ShadeController.cs" />

View File

@@ -358,27 +358,14 @@ namespace PepperDash.Essentials
try try
{ {
var assy = loadedAssembly.Assembly; var assy = loadedAssembly.Assembly;
CType[] types = {}; var types = assy.GetTypes();
try
{
types = assy.GetTypes();
}
catch (TypeLoadException e)
{
Debug.Console(0, Debug.ErrorLogLevel.Warning, "Unable to get types for assembly {0}: {1}",
loadedAssembly.Name, e.Message);
Debug.Console(2, e.StackTrace);
continue;
}
foreach (var type in types) foreach (var type in types)
{ {
try try
{ {
if (typeof (IPluginDeviceFactory).IsAssignableFrom(type)) if (typeof(IPluginDeviceFactory).IsAssignableFrom(type))
{ {
var plugin = var plugin = (IPluginDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
(IPluginDeviceFactory) Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
LoadCustomPlugin(plugin, loadedAssembly); LoadCustomPlugin(plugin, loadedAssembly);
} }
else else
@@ -391,15 +378,10 @@ namespace PepperDash.Essentials
} }
} }
} }
catch (NotSupportedException e)
{
//this happens for dlls that aren't PD dlls, like ports of Mono classes into S#. Swallowing.
}
catch (Exception e) catch (Exception e)
{ {
Debug.Console(2, "Load Plugin not found. {0}.{2} is not a plugin factory. Exception: {1}", Debug.Console(2, "Load Plugin not found. {0}.{2} is not a plugin factory. Exception: {1}",
loadedAssembly.Name, e.Message, type.Name); loadedAssembly.Name, e, type.Name);
continue; continue;
} }
@@ -407,9 +389,7 @@ namespace PepperDash.Essentials
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Console(0, Debug.ErrorLogLevel.Warning, "Error Loading assembly {0}: {1}", Debug.Console(2, "Error Loading Assembly: {0} Exception: {1} ", loadedAssembly.Name, e);
loadedAssembly.Name, e.Message);
Debug.Console(2, "{0}", e.StackTrace);
continue; continue;
} }
} }

View File

@@ -78,23 +78,15 @@ namespace PepperDash_Essentials_Core.Queues
/// IBasicCommunication Message for IQueue /// IBasicCommunication Message for IQueue
/// </summary> /// </summary>
[Obsolete("Use PepperDash.Essentials.Core.Queues")] [Obsolete("Use PepperDash.Essentials.Core.Queues")]
public class ComsMessage : IQueueMessage public class ComsMessage : PepperDash.Essentials.Core.Queues.ComsMessage
{ {
private readonly byte[] _bytes;
private readonly IBasicCommunication _coms;
private readonly string _string;
private readonly bool _isByteMessage;
/// <summary> /// <summary>
/// Constructor for a string message /// Constructor for a string message
/// </summary> /// </summary>
/// <param name="coms">IBasicCommunication to send the message</param> /// <param name="coms">IBasicCommunication to send the message</param>
/// <param name="message">Message to send</param> /// <param name="message">Message to send</param>
public ComsMessage(IBasicCommunication coms, string message) public ComsMessage(IBasicCommunication coms, string message):base(coms, message)
{ {
Validate(coms, message);
_coms = coms;
_string = message;
} }
/// <summary> /// <summary>
@@ -102,44 +94,8 @@ namespace PepperDash_Essentials_Core.Queues
/// </summary> /// </summary>
/// <param name="coms">IBasicCommunication to send the message</param> /// <param name="coms">IBasicCommunication to send the message</param>
/// <param name="message">Message to send</param> /// <param name="message">Message to send</param>
public ComsMessage(IBasicCommunication coms, byte[] message) public ComsMessage(IBasicCommunication coms, byte[] message):base(coms, message)
{ {
Validate(coms, message);
_coms = coms;
_bytes = message;
_isByteMessage = true;
}
private void Validate(IBasicCommunication coms, object message)
{
if (coms == null)
throw new ArgumentNullException("coms");
if (message == null)
throw new ArgumentNullException("message");
}
/// <summary>
/// Dispatchs the string/byte[] to the IBasicCommunication specified
/// </summary>
public void Dispatch()
{
if (_isByteMessage)
{
_coms.SendBytes(_bytes);
}
else
{
_coms.SendText(_string);
}
}
/// <summary>
/// Shows either the byte[] or string to be sent
/// </summary>
public override string ToString()
{
return _bytes != null ? _bytes.ToString() : _string;
} }
} }
} }

View File

@@ -14,7 +14,7 @@ namespace PepperDash.Essentials.Core.Queues
protected readonly CrestronQueue<IQueueMessage> _queue; protected readonly CrestronQueue<IQueueMessage> _queue;
protected readonly Thread _worker; protected readonly Thread _worker;
protected readonly CEvent _waitHandle = new CEvent(); protected readonly CEvent _waitHandle = new CEvent();
private bool _delayEnabled; private bool _delayEnabled;
private int _delayTime; private int _delayTime;
@@ -155,267 +155,10 @@ namespace PepperDash.Essentials.Core.Queues
if (programEvent != eProgramStatusEventType.Stopping) if (programEvent != eProgramStatusEventType.Stopping)
return; return;
Dispose(true); Dispose();
}; };
} }
/// <summary>
/// Thread callback
/// </summary>
/// <param name="obj">The action used to process dequeued items</param>
/// <returns>Null when the thread is exited</returns>
private object ProcessQueue(object obj)
{
while (true)
{
IQueueMessage item = null;
if (_queue.Count > 0)
{
item = _queue.Dequeue();
if (item == null)
break;
}
if (item != null)
{
try
{
//Debug.Console(2, this, "Processing queue item: '{0}'", item.ToString());
item.Dispatch();
if (_delayEnabled)
Thread.Sleep(_delayTime);
}
catch (Exception ex)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
}
}
else _waitHandle.Wait();
}
return null;
}
public void Enqueue(IQueueMessage item)
{
if (Disposed)
{
Debug.Console(1, this, "I've been disposed so you can't enqueue any messages. Are you trying to dispatch a message while the program is stopping?");
return;
}
_queue.Enqueue(item);
_waitHandle.Set();
}
/// <summary>
/// Disposes the thread and cleans up resources. Thread cannot be restarted once
/// disposed.
/// </summary>
public void Dispose()
{
Dispose(true);
CrestronEnvironment.GC.SuppressFinalize(this);
}
/// <summary>
/// Actually does the disposing. If you override this method, be sure to either call the base implementation
/// or clean up all the resources yourself.
/// </summary>
/// <param name="disposing">set to true unless called from finalizer</param>
protected void Dispose(bool disposing)
{
if (Disposed)
return;
if (disposing)
{
Debug.Console(2, this, "Disposing...");
if (_queue != null && !_queue.Disposed)
{
_queue.Clear();
Enqueue(null);
}
_worker.Abort();
_waitHandle.Close();
}
Disposed = true;
}
~GenericQueue()
{
Dispose(true);
}
/// <summary>
/// Key
/// </summary>
public string Key
{
get { return _key; }
}
}
}
namespace PepperDash_Essentials_Core.Queues
{
/// <summary>
/// Threadsafe processing of queued items with pacing if required
/// </summary>
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
public class GenericQueue : IQueue<IQueueMessage>
{
private readonly string _key;
protected readonly CrestronQueue<IQueueMessage> _queue;
protected readonly Thread _worker;
protected readonly CEvent _waitHandle = new CEvent();
private bool _delayEnabled;
private int _delayTime;
private const Thread.eThreadPriority _defaultPriority = Thread.eThreadPriority.MediumPriority;
/// <summary>
/// If the instance has been disposed.
/// </summary>
public bool Disposed { get; private set; }
/// <summary>
/// Returns the capacity of the CrestronQueue (fixed Size property)
/// </summary>
public int QueueCapacity
{
get
{
return _queue.Size;
}
}
/// <summary>
/// Returns the number of elements currently in the CrestronQueue
/// </summary>
public int QueueCount
{
get
{
return _queue.Count;
}
}
/// <summary>
/// Constructor with no thread priority
/// </summary>
/// <param name="key"></param>
public GenericQueue(string key)
: this(key, _defaultPriority, 0, 0)
{
}
/// <summary>
/// Constructor with queue size
/// </summary>
/// <param name="key"></param>
/// <param name="capacity">Fixed size for the queue to hold</param>
public GenericQueue(string key, int capacity)
: this(key, _defaultPriority, capacity, 0)
{
}
/// <summary>
/// Constructor for generic queue with no pacing
/// </summary>
/// <param name="key">Key</param>
/// <param name="pacing">Pacing in ms between actions</param>
public GenericQueue(int pacing, string key)
: this(key, _defaultPriority, 0, pacing)
{
}
/// <summary>
/// Constructor with pacing and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, int pacing, int capacity)
: this(key, _defaultPriority, capacity, pacing)
{
}
/// <summary>
/// Constructor with pacing and priority
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="priority"></param>
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority)
: this(key, priority, 0, pacing)
{
}
/// <summary>
/// Constructor with pacing, priority and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, Thread.eThreadPriority priority, int capacity)
: this(key, priority, capacity, 0)
{
}
/// <summary>
/// Constructor with pacing, priority and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority, int capacity)
: this(key, priority, capacity, pacing)
{
}
/// <summary>
/// Constructor for generic queue with no pacing
/// </summary>
/// <param name="key">Key</param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
/// <param name="pacing"></param>
protected GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing)
{
_key = key;
int cap = 25; // sets default
if (capacity > 0)
{
cap = capacity; // overrides default
}
_queue = new CrestronQueue<IQueueMessage>(cap);
_worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running)
{
Priority = priority
};
SetDelayValues(pacing);
}
private void SetDelayValues(int pacing)
{
_delayEnabled = pacing > 0;
_delayTime = pacing;
CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
{
if (programEvent != eProgramStatusEventType.Stopping)
return;
Dispose(true);
};
}
/// <summary> /// <summary>
/// Thread callback /// Thread callback
/// </summary> /// </summary>
@@ -482,13 +225,8 @@ namespace PepperDash_Essentials_Core.Queues
if (disposing) if (disposing)
{ {
Debug.Console(2, this, "Disposing..."); Enqueue(null);
if (_queue != null && !_queue.Disposed) _worker.Join();
{
_queue.Clear();
Enqueue(null);
}
_worker.Abort();
_waitHandle.Close(); _waitHandle.Close();
} }
@@ -497,7 +235,7 @@ namespace PepperDash_Essentials_Core.Queues
~GenericQueue() ~GenericQueue()
{ {
Dispose(true); Dispose(false);
} }
/// <summary> /// <summary>
@@ -508,4 +246,106 @@ namespace PepperDash_Essentials_Core.Queues
get { return _key; } get { return _key; }
} }
} }
}
namespace PepperDash_Essentials_Core.Queues
{
/// <summary>
/// Threadsafe processing of queued items with pacing if required
/// </summary>
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
public class GenericQueue : PepperDash.Essentials.Core.Queues.GenericQueue
{
private bool _delayEnabled;
private int _delayTime;
private const Thread.eThreadPriority _defaultPriority = Thread.eThreadPriority.MediumPriority;
/// <summary>
/// Constructor with no thread priority
/// </summary>
/// <param name="key"></param>
public GenericQueue(string key)
: this(key, _defaultPriority, 0, 0)
{
}
/// <summary>
/// Constructor with queue size
/// </summary>
/// <param name="key"></param>
/// <param name="capacity">Fixed size for the queue to hold</param>
public GenericQueue(string key, int capacity)
: this(key, _defaultPriority, capacity, 0)
{
}
/// <summary>
/// Constructor for generic queue with no pacing
/// </summary>
/// <param name="key">Key</param>
/// <param name="pacing">Pacing in ms between actions</param>
public GenericQueue(int pacing, string key)
: this(key, _defaultPriority, 0, pacing)
{
}
/// <summary>
/// Constructor with pacing and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, int pacing, int capacity)
: this(key, _defaultPriority, capacity, pacing)
{
}
/// <summary>
/// Constructor with pacing and priority
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="priority"></param>
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority)
: this(key, priority, 0, pacing)
{
}
/// <summary>
/// Constructor with pacing, priority and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, Thread.eThreadPriority priority, int capacity)
: this(key, priority, capacity, 0)
{
}
/// <summary>
/// Constructor with pacing, priority and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority, int capacity)
: this(key, priority, capacity, pacing)
{
}
/// <summary>
/// Constructor for generic queue with no pacing
/// </summary>
/// <param name="key">Key</param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
/// <param name="pacing"></param>
private GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing):base(key, priority, capacity, pacing)
{
}
}
} }

View File

@@ -17,9 +17,7 @@ namespace PepperDash.Essentials.Core.Queues
namespace PepperDash_Essentials_Core.Queues namespace PepperDash_Essentials_Core.Queues
{ {
[Obsolete("Use PepperDash.Essentials.Core.Queues")] [Obsolete("Use PepperDash.Essentials.Core.Queues")]
public interface IQueue<T> : IKeyed, IDisposable where T : class public interface IQueue<T> : PepperDash.Essentials.Core.Queues.IQueue<T> where T: class
{ {
void Enqueue(T item);
bool Disposed { get; }
} }
} }

View File

@@ -11,8 +11,7 @@ namespace PepperDash.Essentials.Core.Queues
namespace PepperDash_Essentials_Core.Queues namespace PepperDash_Essentials_Core.Queues
{ {
[Obsolete("Use PepperDash.Essentials.Core.Queues")] [Obsolete("Use PepperDash.Essentials.Core.Queues")]
public interface IQueueMessage public interface IQueueMessage:PepperDash.Essentials.Core.Queues.IQueueMessage
{ {
void Dispatch();
} }
} }

View File

@@ -49,40 +49,13 @@ namespace PepperDash_Essentials_Core.Queues
/// Message class for processing strings via an IQueue /// Message class for processing strings via an IQueue
/// </summary> /// </summary>
[Obsolete("Use PepperDash.Essentials.Core.Queues")] [Obsolete("Use PepperDash.Essentials.Core.Queues")]
public class ProcessStringMessage : IQueueMessage public class ProcessStringMessage : PepperDash.Essentials.Core.Queues.ProcessStringMessage
{ {
private readonly Action<string> _action;
private readonly string _message;
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
/// <param name="message">Message to be processed</param> /// <param name="message">Message to be processed</param>
/// <param name="action">Action to invoke on the message</param> /// <param name="action">Action to invoke on the message</param>
public ProcessStringMessage(string message, Action<string> action) public ProcessStringMessage(string message, Action<string> action) : base(message, action){}
{
_message = message;
_action = action;
}
/// <summary>
/// Processes the string with the given action
/// </summary>
public void Dispatch()
{
if (_action == null || String.IsNullOrEmpty(_message))
return;
_action(_message);
}
/// <summary>
/// To string
/// </summary>
/// <returns>The current message</returns>
public override string ToString()
{
return _message ?? String.Empty;
}
} }
} }

View File

@@ -111,14 +111,14 @@ namespace PepperDash_Essentials_Core.Queues
public sealed class StringResponseProcessor : IKeyed, IDisposable public sealed class StringResponseProcessor : IKeyed, IDisposable
{ {
private readonly Action<string> _processStringAction; private readonly Action<string> _processStringAction;
private readonly IQueue<IQueueMessage> _queue; private readonly PepperDash.Essentials.Core.Queues.IQueue<PepperDash.Essentials.Core.Queues.IQueueMessage> _queue;
private readonly IBasicCommunication _coms; private readonly IBasicCommunication _coms;
private readonly CommunicationGather _gather; private readonly CommunicationGather _gather;
private StringResponseProcessor(string key, Action<string> processStringAction) private StringResponseProcessor(string key, Action<string> processStringAction)
{ {
_processStringAction = processStringAction; _processStringAction = processStringAction;
_queue = new GenericQueue(key); _queue = new PepperDash.Essentials.Core.Queues.GenericQueue(key);
CrestronEnvironment.ProgramStatusEventHandler += programEvent => CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
{ {

View File

@@ -169,15 +169,10 @@ namespace PepperDash.Essentials.Core
void FeatureEventGroup_UserGroupCallBack(ScheduledEvent SchEvent, ScheduledEventCommon.eCallbackReason type) void FeatureEventGroup_UserGroupCallBack(ScheduledEvent SchEvent, ScheduledEventCommon.eCallbackReason type)
{ {
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "{0}:{1} @ {2}", SchEvent.Name, type, DateTime.Now);
if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration) if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration)
{ {
SchEvent.Acknowledge();
if (SchEvent.Name == FeatureEnableEventName) if (SchEvent.Name == FeatureEnableEventName)
{ {
if (PropertiesConfig.EnableRoomOnWhenOccupied) if (PropertiesConfig.EnableRoomOnWhenOccupied)
FeatureEnabled = true; FeatureEnabled = true;
@@ -253,8 +248,9 @@ namespace PepperDash.Essentials.Core
schEvent = new ScheduledEvent(name, FeatureEventGroup); schEvent = new ScheduledEvent(name, FeatureEventGroup);
// Set up its initial properties // Set up its initial properties
schEvent.Acknowledgeable = false; if(!schEvent.Acknowledgeable)
schEvent.Acknowledgeable = true;
if(!schEvent.Persistent) if(!schEvent.Persistent)
schEvent.Persistent = true; schEvent.Persistent = true;
@@ -291,7 +287,7 @@ namespace PepperDash.Essentials.Core
Debug.Console(1, this, "Event '{0}' Absolute time set to {1}", schEvent.Name, schEvent.DateAndTime.ToString()); Debug.Console(1, this, "Event '{0}' Absolute time set to {1}", schEvent.Name, schEvent.DateAndTime.ToString());
//CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime); CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime);
schEvent.Recurrence.Weekly(eventRecurrennce); schEvent.Recurrence.Weekly(eventRecurrennce);

View File

@@ -123,34 +123,25 @@ namespace PepperDash.Essentials.Core
// No direct tie? Run back out on the inputs' attached devices... // No direct tie? Run back out on the inputs' attached devices...
// Only the ones that are routing devices // Only the ones that are routing devices
var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs); var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs);
//Create a list for tracking already checked devices to avoid loops, if it doesn't already exist from previous iteration
if (alreadyCheckedDevices == null)
alreadyCheckedDevices = new List<IRoutingInputsOutputs>();
alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs);
foreach (var inputTieToTry in attachedMidpoints) foreach (var inputTieToTry in attachedMidpoints)
{ {
Debug.Console(2, destination, "Trying to find route on {0}", inputTieToTry.SourcePort.ParentDevice.Key);
var upstreamDeviceOutputPort = inputTieToTry.SourcePort; var upstreamDeviceOutputPort = inputTieToTry.SourcePort;
var upstreamRoutingDevice = upstreamDeviceOutputPort.ParentDevice as IRoutingInputsOutputs; var upstreamRoutingDevice = upstreamDeviceOutputPort.ParentDevice as IRoutingInputsOutputs;
Debug.Console(2, destination, "Trying to find route on {0}", upstreamRoutingDevice.Key);
// Check if this previous device has already been walked // Check if this previous device has already been walked
if (alreadyCheckedDevices.Contains(upstreamRoutingDevice)) if (!(alreadyCheckedDevices != null && alreadyCheckedDevices.Contains(upstreamRoutingDevice)))
{ {
Debug.Console(2, destination, "Skipping input {0} on {1}, this was already checked", upstreamRoutingDevice.Key, destination.Key); // haven't seen this device yet. Do it. Pass the output port to the next
continue; // level to enable switching on success
} var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
// haven't seen this device yet. Do it. Pass the output port to the next alreadyCheckedDevices, signalType, cycle, routeTable);
// level to enable switching on success if (upstreamRoutingSuccess)
var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort, {
alreadyCheckedDevices, signalType, cycle, routeTable); Debug.Console(2, destination, "Upstream device route found");
if (upstreamRoutingSuccess) goodInputPort = inputTieToTry.DestinationPort;
{ break; // Stop looping the inputs in this cycle
Debug.Console(2, destination, "Upstream device route found"); }
goodInputPort = inputTieToTry.DestinationPort; }
break; // Stop looping the inputs in this cycle
}
} }
} }
@@ -172,6 +163,10 @@ namespace PepperDash.Essentials.Core
//Debug.Console(2, destination, "Exiting cycle {0}", cycle); //Debug.Console(2, destination, "Exiting cycle {0}", cycle);
return true; return true;
} }
if(alreadyCheckedDevices == null)
alreadyCheckedDevices = new List<IRoutingInputsOutputs>();
alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs);
Debug.Console(2, destination, "No route found to {0}", source.Key); Debug.Console(2, destination, "No route found to {0}", source.Key);
return false; return false;

View File

@@ -1,97 +0,0 @@
using System;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronDataStore;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public class CrestronSecretsProvider : ISecretProvider
{
public string Key { get; set; }
//Added for reference
private static readonly bool SecureSupported;
public CrestronSecretsProvider(string key)
{
Key = key;
}
static CrestronSecretsProvider()
{
//Added for future encrypted reference
SecureSupported = CrestronSecureStorage.Supported;
CrestronDataStoreStatic.InitCrestronDataStore();
if (SecureSupported)
{
//doThingsFuture
}
}
/// <summary>
/// Set secret for item in the CrestronSecretsProvider
/// </summary>
/// <param name="key">Secret Key</param>
/// <param name="value">Secret Value</param>
public bool SetSecret(string key, object value)
{
var secret = value as string;
if (String.IsNullOrEmpty(secret))
{
Debug.Console(2, this, "Unable to set secret for {0}:{1} - value is empty.", Key, key);
return false;
}
var setErrorCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret);
switch (setErrorCode)
{
case CrestronDataStore.CDS_ERROR.CDS_SUCCESS:
Debug.Console(1, this,"Secret Successfully Set for {0}:{1}", Key, key);
return true;
default:
Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, setErrorCode.ToString());
return false;
}
}
/// <summary>
/// Retrieve secret for item in the CrestronSecretsProvider
/// </summary>
/// <param name="key">Secret Key</param>
/// <returns>ISecret Object containing key, provider, and value</returns>
public ISecret GetSecret(string key)
{
string mySecret;
var getErrorCode = CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret);
switch (getErrorCode)
{
case CrestronDataStore.CDS_ERROR.CDS_SUCCESS:
Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key);
return new CrestronSecret(key, mySecret, this);
default:
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}",
Key, key, getErrorCode.ToString());
return null;
}
}
}
/// <summary>
/// Special container class for CrestronSecret provider
/// </summary>
public class CrestronSecret : ISecret
{
public ISecretProvider Provider { get; private set; }
public string Key { get; private set; }
public object Value { get; private set; }
public CrestronSecret(string key, string value, ISecretProvider provider)
{
Key = key;
Value = value;
Provider = provider;
}
}
}

View File

@@ -1,24 +0,0 @@
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// All ISecrecretProvider classes must implement this interface.
/// </summary>
public interface ISecretProvider : IKeyed
{
bool SetSecret(string key, object value);
ISecret GetSecret(string key);
}
/// <summary>
/// interface for delivering secrets in Essentials.
/// </summary>
public interface ISecret
{
ISecretProvider Provider { get; }
string Key { get; }
object Value { get; }
}
}

View File

@@ -1,281 +0,0 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public static class SecretsManager
{
public static Dictionary<string, ISecretProvider> Secrets { get; private set; }
/// <summary>
/// Initialize the SecretsManager
/// </summary>
public static void Initialize()
{
AddSecretProvider("default", new CrestronSecretsProvider("default"));
CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret",
"Adds secrets to secret provider",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(UpdateSecretProcess, "updatesecret",
"Updates secrets in secret provider",
ConsoleAccessLevelEnum.AccessAdministrator);
CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret",
"Deletes secrets in secret provider",
ConsoleAccessLevelEnum.AccessAdministrator);
}
static SecretsManager()
{
Secrets = new Dictionary<string, ISecretProvider>();
}
/// <summary>
/// Get Secret Provider from dictionary by key
/// </summary>
/// <param name="key">Dictionary Key for provider</param>
/// <returns>ISecretProvider</returns>
public static ISecretProvider GetSecretProviderByKey(string key)
{
ISecretProvider secret;
Secrets.TryGetValue(key, out secret);
if (secret == null)
{
Debug.Console(1, "SecretsManager unable to retrieve SecretProvider with the key '{0}'", key);
}
return secret;
}
/// <summary>
/// Add secret provider to secrets dictionary
/// </summary>
/// <param name="key">Key of new entry</param>
/// <param name="provider">New Provider Entry</param>
public static void AddSecretProvider(string key, ISecretProvider provider)
{
if (!Secrets.ContainsKey(key))
{
Secrets.Add(key, provider);
Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key);
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key );
}
/// <summary>
/// Add secret provider to secrets dictionary, with optional overwrite parameter
/// </summary>
/// <param name="key">Key of new entry</param>
/// <param name="provider">New provider entry</param>
/// <param name="overwrite">true to overwrite any existing providers in the dictionary</param>
public static void AddSecretProvider(string key, ISecretProvider provider, bool overwrite)
{
if (!Secrets.ContainsKey(key))
{
Secrets.Add(key, provider);
Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key);
}
if (overwrite)
{
Secrets.Add(key, provider);
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Provider with the key '{0}' already exists in secrets. Overwriting with new secrets provider.", key);
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key);
}
private static void SetSecretProcess(string cmd)
{
string response;
var args = cmd.Split(' ');
if (args.Length == 0)
{
//some Instructional Text
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length == 1 && args[0] == "?")
{
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length < 3)
{
response = "Improper number of arguments";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
var provider = GetSecretProviderByKey(args[0]);
if (provider == null)
{
//someFail
response = "Provider key invalid";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
var key = args[1];
var secret = args[2];
if (provider.GetSecret(key) == null)
{
response = provider.SetSecret(key, secret)
? String.Format(
"Secret successfully set for {0}:{1}",
provider.Key, key)
: String.Format(
"Unable to set secret for {0}:{1}",
provider.Key, key);
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response =
String.Format(
"Unable to set secret for {0}:{1} - Please use the 'UpdateSecret' command to modify it");
CrestronConsole.ConsoleCommandResponse(response);
}
private static void UpdateSecretProcess(string cmd)
{
string response;
var args = cmd.Split(' ');
if (args.Length == 0)
{
//some Instructional Text
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length == 1 && args[0] == "?")
{
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length < 3)
{
//someFail
response = "Improper number of arguments";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
var provider = GetSecretProviderByKey(args[0]);
if (provider == null)
{
//someFail
response = "Provider key invalid";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
var key = args[1];
var secret = args[2];
if (provider.GetSecret(key) != null)
{
response = provider.SetSecret(key, secret)
? String.Format(
"Secret successfully set for {0}:{1}",
provider.Key, key)
: String.Format(
"Unable to set secret for {0}:{1}",
provider.Key, key);
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response =
String.Format(
"Unable to update secret for {0}:{1} - Please use the 'SetSecret' command to create a new secret");
CrestronConsole.ConsoleCommandResponse(response);
}
private static void DeleteSecretProcess(string cmd)
{
string response;
var args = cmd.Split(' ');
if (args.Length == 0)
{
//some Instructional Text
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length == 1 && args[0] == "?")
{
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length < 2)
{
//someFail
response = "Improper number of arguments";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
var provider = GetSecretProviderByKey(args[0]);
if (provider == null)
{
//someFail
response = "Provider key invalid";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
var key = args[1];
provider.SetSecret(key, "");
response = provider.SetSecret(key, "")
? String.Format(
"Secret successfully deleted for {0}:{1}",
provider.Key, key)
: String.Format(
"Unable to delete secret for {0}:{1}",
provider.Key, key);
CrestronConsole.ConsoleCommandResponse(response);
return;
}
}
}

View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Provide a way to easily deserialize into a secret object from config
/// </summary>
public class SecretsPropertiesConfig
{
[JsonProperty("provider")]
public string Provider { get; set; }
[JsonProperty("key")]
public string Key { get; set; }
}
}

View File

@@ -671,7 +671,7 @@ namespace PepperDash.Essentials.DM {
var ioSlotJoin = ioSlot - 1; var ioSlotJoin = ioSlot - 1;
// Control // Control
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video)); trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video));
if (TxDictionary.ContainsKey(ioSlot)) if (TxDictionary.ContainsKey(ioSlot))
{ {

View File

@@ -228,9 +228,9 @@ namespace PepperDash.Essentials.DM
// Control // Control
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin,
o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video)); o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video));
trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin, trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin,
o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Audio)); o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio));
trilist.SetStringSigAction(joinMap.OutputNames.JoinNumber + ioSlotJoin, s => trilist.SetStringSigAction(joinMap.OutputNames.JoinNumber + ioSlotJoin, s =>
{ {

View File

@@ -48,15 +48,15 @@
<ItemGroup> <ItemGroup>
<Reference Include="Crestron.SimplSharpPro.DeviceSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.DeviceSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.DM, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.DM, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
</Reference> </Reference>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
<Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
@@ -65,26 +65,26 @@
</Reference> </Reference>
<Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="SimplSharpHelperInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpHelperInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="SimplSharpNewtonsoft, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpNewtonsoft, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll</HintPath>
</Reference> </Reference>
<Reference Include="SimplSharpPro, Version=1.5.3.17, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpPro, Version=1.5.3.17, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="SimplSharpReflectionInterface, Version=1.0.5583.25238, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpReflectionInterface, Version=1.0.5583.25238, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />

View File

@@ -8,8 +8,6 @@ using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Core.Presets;
using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.Codec;
@@ -27,7 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
Focus = 8 Focus = 8
} }
public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs public abstract class CameraBase : EssentialsDevice, IRoutingOutputs
{ {
public eCameraControlMode ControlMode { get; protected set; } public eCameraControlMode ControlMode { get; protected set; }
@@ -72,18 +70,12 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
// A bitmasked value to indicate the movement capabilites of this camera // A bitmasked value to indicate the movement capabilites of this camera
protected eCameraCapabilities Capabilities { get; set; } protected eCameraCapabilities Capabilities { get; set; }
protected CameraBase(DeviceConfig config) : base(config) protected CameraBase(string key, string name) :
{ base(key, name)
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
ControlMode = eCameraControlMode.Manual;
}
protected CameraBase(string key, string name) :
this (new DeviceConfig{Name = name, Key = key})
{ {
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
ControlMode = eCameraControlMode.Manual;
} }
protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey, protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey,

View File

@@ -165,6 +165,12 @@ namespace PepperDash.Essentials.Devices.Common.DSP
/// <param name="args"></param> /// <param name="args"></param>
private void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) private void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
{ {
if (Debug.Level == 2)
Debug.Console(2, this, "RX: '{0}'",
ShowHexResponse ? ComTextHelper.GetEscapedText(args.Text) : args.Text);
Debug.Console(1, this, "RX: '{0}'", args.Text);
try try
{ {
if (args.Text.IndexOf("Welcome to the Tesira Text Protocol Server...") > -1) if (args.Text.IndexOf("Welcome to the Tesira Text Protocol Server...") > -1)
@@ -282,6 +288,7 @@ namespace PepperDash.Essentials.Devices.Common.DSP
/// <param name="s">Command to send</param> /// <param name="s">Command to send</param>
public void SendLine(string s) public void SendLine(string s)
{ {
Debug.Console(1, this, "TX: '{0}'", s);
Communication.SendText(s + "\x0a"); Communication.SendText(s + "\x0a");
} }

View File

@@ -232,6 +232,7 @@ namespace PepperDash.Essentials.Devices.Common.Environment.Lutron
/// <param name="s"></param> /// <param name="s"></param>
public void SendLine(string s) public void SendLine(string s)
{ {
Debug.Console(2, this, "TX: '{0}'", s);
Communication.SendText(s + Delimiter); Communication.SendText(s + Delimiter);
} }
} }

View File

@@ -48,19 +48,19 @@
<ItemGroup> <ItemGroup>
<Reference Include="Crestron.SimplSharpPro.DeviceSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.DeviceSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.Gateways, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.Gateways, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.GeneralIO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.GeneralIO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll</HintPath>
</Reference> </Reference>
<Reference Include="Crestron.SimplSharpPro.Lighting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="Crestron.SimplSharpPro.Lighting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Lighting.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Lighting.dll</HintPath>
</Reference> </Reference>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
<Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
@@ -69,26 +69,26 @@
</Reference> </Reference>
<Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="SimplSharpHelperInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpHelperInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="SimplSharpNewtonsoft, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpNewtonsoft, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll</HintPath>
</Reference> </Reference>
<Reference Include="SimplSharpPro, Version=1.5.3.17, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpPro, Version=1.5.3.17, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="SimplSharpReflectionInterface, Version=1.0.5583.25238, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL"> <Reference Include="SimplSharpReflectionInterface, Version=1.0.5583.25238, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@@ -176,7 +176,6 @@
<Compile Include="VideoCodec\ZoomRoom\ResponseObjects.cs" /> <Compile Include="VideoCodec\ZoomRoom\ResponseObjects.cs" />
<Compile Include="VideoCodec\ZoomRoom\ZoomRoom.cs" /> <Compile Include="VideoCodec\ZoomRoom\ZoomRoom.cs" />
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomCamera.cs" /> <Compile Include="VideoCodec\ZoomRoom\ZoomRoomCamera.cs" />
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomJoinMap.cs" />
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomPropertiesConfig.cs" /> <Compile Include="VideoCodec\ZoomRoom\ZoomRoomPropertiesConfig.cs" />
<None Include="Properties\ControlSystem.cfg" /> <None Include="Properties\ControlSystem.cfg" />
</ItemGroup> </ItemGroup>

View File

@@ -133,6 +133,7 @@ namespace PepperDash.Essentials.Devices.Common
/// <param name="args"></param> /// <param name="args"></param>
void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
{ {
Debug.Console(2, this, "TVOneCurio RX: '{0}'", args.Text);
try try
{ {
if (args.Text.IndexOf("login") > -1) if (args.Text.IndexOf("login") > -1)
@@ -141,18 +142,24 @@ namespace PepperDash.Essentials.Devices.Common
} }
else if (args.Text.IndexOf("!Done Preset.Take =") > -1) else if (args.Text.IndexOf("!Done Preset.Take =") > -1)
{ {
string presetNumberParse = args.Text.Remove(0, args.Text.IndexOf("=") + 2); string presetNumberParse = args.Text.Remove(0, args.Text.IndexOf("=") + 2);
Debug.Console(1, this, "Preset Parse: {0}", presetNumberParse); Debug.Console(1, this, "Preset Parse: {0}", presetNumberParse);
CurrentPreset = ushort.Parse(presetNumberParse); CurrentPreset = ushort.Parse(presetNumberParse);
PresetFeedback.FireUpdate(); PresetFeedback.FireUpdate();
}
}
} }
catch (Exception e) catch (Exception e)
{ {
if (Debug.Level == 2) if (Debug.Level == 2)
Debug.Console(2, this, "Error parsing response: '{0}'\n{1}", args.Text, e); Debug.Console(2, this, "Error parsing response: '{0}'\n{1}", args.Text, e);
} }
} }
/// <summary> /// <summary>
@@ -161,6 +168,7 @@ namespace PepperDash.Essentials.Devices.Common
/// <param name="s">Command to send</param> /// <param name="s">Command to send</param>
public void SendLine(string s) public void SendLine(string s)
{ {
Debug.Console(1, this, "TVOne Cusio TX: '{0}'", s);
Communication.SendText(s + "\x0d\x0a"); Communication.SendText(s + "\x0d\x0a");
} }

View File

@@ -133,6 +133,7 @@ namespace PepperDash.Essentials.Devices.Common
/// <param name="args"></param> /// <param name="args"></param>
void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
{ {
Debug.Console(2, this, "TVOneCurio RX: '{0}'", args.Text);
try try
{ {
if (args.Text.IndexOf("login") > -1) if (args.Text.IndexOf("login") > -1)
@@ -147,7 +148,11 @@ namespace PepperDash.Essentials.Devices.Common
Debug.Console(1, this, "Preset Parse: {0}", presetNumberParse); Debug.Console(1, this, "Preset Parse: {0}", presetNumberParse);
CurrentPreset = ushort.Parse(presetNumberParse); CurrentPreset = ushort.Parse(presetNumberParse);
PresetFeedback.FireUpdate(); PresetFeedback.FireUpdate();
}
}
} }
catch (Exception e) catch (Exception e)
{ {
@@ -163,6 +168,7 @@ namespace PepperDash.Essentials.Devices.Common
/// <param name="s">Command to send</param> /// <param name="s">Command to send</param>
public void SendLine(string s) public void SendLine(string s)
{ {
Debug.Console(1, this, "TVOne Cusio TX: '{0}'", s);
Communication.SendText(s + "\x0d\x0a"); Communication.SendText(s + "\x0d\x0a");
} }

View File

@@ -219,6 +219,8 @@ namespace PepperDash.Essentials.Devices.Common
string url = string.Format("http://{0}{1}", this.address, s); string url = string.Format("http://{0}{1}", this.address, s);
request.Url = new UrlParser(url); request.Url = new UrlParser(url);
HttpClientResponse response = WebClient.Dispatch(request); HttpClientResponse response = WebClient.Dispatch(request);
Debug.Console(2, this, "DigitalLogger TX:\n'{0}'\nRX:\n'{1}'", url, response.ContentString);
return response.ContentString; return response.ContentString;
} }
/// <summary> /// <summary>
@@ -234,6 +236,9 @@ namespace PepperDash.Essentials.Devices.Common
request.Url = new UrlParser(url); request.Url = new UrlParser(url);
HttpClientResponse response = WebClient.Dispatch(request); HttpClientResponse response = WebClient.Dispatch(request);
Debug.Console(2, this, "DigitalLogger TX:\n'{0}'\nRX:\n'{1}'", url, response.ContentString);
} }
public void CycleCircuit(uint circuit) public void CycleCircuit(uint circuit)

View File

@@ -30,8 +30,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView, IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView,
ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute
{ {
private bool _externalSourceChangeRequested;
public event EventHandler<DirectoryEventArgs> DirectoryResultReturned; public event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
private CTimer _brandingTimer; private CTimer _brandingTimer;
@@ -370,9 +368,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
CodecSchedule = new CodecScheduleAwareness(); CodecSchedule = new CodecScheduleAwareness();
//Set Feedback Actions //Set Feedback Actions
SetFeedbackActions(); CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate;
CodecStatus.Status.Audio.VolumeMute.ValueChangedAction = MuteFeedback.FireUpdate;
CodecStatus.Status.Audio.Microphones.Mute.ValueChangedAction = PrivacyModeIsOnFeedback.FireUpdate;
CodecStatus.Status.Standby.State.ValueChangedAction = StandbyIsOnFeedback.FireUpdate;
CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate;
CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate;
CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = CameraAutoModeIsOnFeedback.FireUpdate;
CodecStatus.Status.Video.Selfview.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate;
CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus;
CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout;
CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = SharingContentIsOnFeedback.FireUpdate;
CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = FarEndIsSharingContentFeedback.FireUpdate;
CodecStatus.Status.Video.Input.MainVideoMute.ValueChangedAction = CameraIsOffFeedback.FireUpdate;
CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.Audio | eRoutingSignalType.Video, CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this); eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this);
HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video, HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource1), this); eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource1), this);
@@ -408,36 +418,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
_brandingUrl = props.UiBranding.BrandingUrl; _brandingUrl = props.UiBranding.BrandingUrl;
} }
private void SetFeedbackActions() /// <summary>
{
CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate;
CodecStatus.Status.Audio.VolumeMute.ValueChangedAction = MuteFeedback.FireUpdate;
CodecStatus.Status.Audio.Microphones.Mute.ValueChangedAction = PrivacyModeIsOnFeedback.FireUpdate;
CodecStatus.Status.Standby.State.ValueChangedAction = StandbyIsOnFeedback.FireUpdate;
CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate;
CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate;
CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = CameraAutoModeIsOnFeedback.FireUpdate;
CodecStatus.Status.Video.Selfview.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate;
CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus;
CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout;
CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = SharingContentIsOnFeedback.FireUpdate;
CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = FarEndIsSharingContentFeedback.FireUpdate;
try
{
CodecStatus.Status.Video.Input.MainVideoMute.ValueChangedAction = CameraIsOffFeedback.FireUpdate;
}
catch (Exception ex)
{
Debug.Console(0, this, "Error setting MainVideuMute Action: {0}", ex);
if (ex.InnerException != null)
{
Debug.Console(0, this, "Error setting MainVideuMute Action: {0}", ex);
}
}
}
/// <summary>
/// Creates the fake OSD source, and connects it's AudioVideo output to the CodecOsdIn input /// Creates the fake OSD source, and connects it's AudioVideo output to the CodecOsdIn input
/// to enable routing /// to enable routing
/// </summary> /// </summary>
@@ -492,21 +473,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
Debug.Console(2, this, "Setting QR code URL: {0}", mcBridge.QrCodeUrl); Debug.Console(2, this, "Setting QR code URL: {0}", mcBridge.QrCodeUrl);
mcBridge.UserCodeChanged += (o, a) => SendMcBrandingUrl(mcBridge); mcBridge.UserCodeChanged += (o, a) => SendMcBrandingUrl(mcBridge);
mcBridge.UserPromptedForCode += (o, a) => DisplayUserCode(mcBridge.UserCode);
SendMcBrandingUrl(mcBridge); SendMcBrandingUrl(mcBridge);
} }
} }
/// <summary>
/// Displays the code for the specified duration
/// </summary>
/// <param name="code">Mobile Control user code</param>
private void DisplayUserCode(string code)
{
SendText(string.Format("xcommand userinterface message alert display title:\"Mobile Control User Code:\" text:\"{0}\" duration: 30", code));
}
private void SendMcBrandingUrl(IMobileControlRoomBridge mcBridge) private void SendMcBrandingUrl(IMobileControlRoomBridge mcBridge)
{ {
if (mcBridge == null) if (mcBridge == null)
@@ -573,7 +544,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
prefix + "/Status/Standby" + Delimiter + prefix + "/Status/Standby" + Delimiter +
prefix + "/Status/Video/Selfview" + Delimiter + prefix + "/Status/Video/Selfview" + Delimiter +
prefix + "/Status/Video/Layout" + Delimiter + prefix + "/Status/Video/Layout" + Delimiter +
prefix + "/Status/Video/Input/MainVideoMute" + Delimiter +
prefix + "/Bookings" + Delimiter + prefix + "/Bookings" + Delimiter +
prefix + "/Event/CallDisconnect" + Delimiter + prefix + "/Event/CallDisconnect" + Delimiter +
prefix + "/Event/Bookings" + Delimiter + prefix + "/Event/Bookings" + Delimiter +
@@ -667,7 +637,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{ {
if (CommDebuggingIsOn) if (CommDebuggingIsOn)
{ {
if (!JsonFeedbackMessageIsIncoming) if(!JsonFeedbackMessageIsIncoming)
Debug.Console(1, this, "RX: '{0}'", args.Text); Debug.Console(1, this, "RX: '{0}'", args.Text);
} }
@@ -963,12 +933,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
JsonConvert.PopulateObject(response, eventReceived); JsonConvert.PopulateObject(response, eventReceived);
Debug.Console(2, this, "*** Got an External Source Selection {0} {1}", eventReceived, eventReceived.Event.UserInterface, eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value); Debug.Console(2, this, "*** Got an External Source Selection {0} {1}", eventReceived, eventReceived.Event.UserInterface, eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value);
if (RunRouteAction != null && !_externalSourceChangeRequested) if (RunRouteAction != null)
{ {
RunRouteAction(eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value, null); RunRouteAction(eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value, null);
} }
_externalSourceChangeRequested = false;
} }
} }
else if (response.IndexOf("\"CommandResponse\":{") > -1 || response.IndexOf("\"CommandResponse\": {") > -1) else if (response.IndexOf("\"CommandResponse\":{") > -1 || response.IndexOf("\"CommandResponse\": {") > -1)
@@ -1665,21 +1633,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public void CameraAutoModeOn() public void CameraAutoModeOn()
{ {
if (CameraIsOffFeedback.BoolValue)
{
CameraMuteOff();
}
SendText("xCommand Cameras SpeakerTrack Activate"); SendText("xCommand Cameras SpeakerTrack Activate");
CameraMuteOff();
} }
public void CameraAutoModeOff() public void CameraAutoModeOff()
{ {
if (CameraIsOffFeedback.BoolValue)
{
CameraMuteOff();
}
SendText("xCommand Cameras SpeakerTrack Deactivate"); SendText("xCommand Cameras SpeakerTrack Deactivate");
} }
@@ -1998,7 +1957,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public void SetSelectedSource(string key) public void SetSelectedSource(string key)
{ {
SendText(string.Format("xCommand UserInterface Presentation ExternalSource Select SourceIdentifier: {0}", key)); SendText(string.Format("xCommand UserInterface Presentation ExternalSource Select SourceIdentifier: {0}", key));
_externalSourceChangeRequested = true;
} }
/// <summary> /// <summary>
@@ -2036,7 +1994,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
/// </summary> /// </summary>
public void CameraMuteOn() public void CameraMuteOn()
{ {
SendText("xCommand Video Input MainVideo Mute"); SendText("xCommand Video InputMainVideo Mute");
} }
/// <summary> /// <summary>
@@ -2044,7 +2002,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
/// </summary> /// </summary>
public void CameraMuteOff() public void CameraMuteOff()
{ {
SendText("xCommand Video Input MainVideo Unmute"); SendText("xCommand Video InputMainVideo Unmute");
} }
/// <summary> /// <summary>

View File

@@ -8,7 +8,6 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.VideoCodec.CiscoCodec;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{ {
@@ -1681,11 +1680,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public MainVideoSource MainVideoSource { get; set; } public MainVideoSource MainVideoSource { get; set; }
public MainVideoMute MainVideoMute { get; set; } public MainVideoMute MainVideoMute { get; set; }
public List<Source> Source { get; set; } public List<Source> Source { get; set; }
public Input2()
{
MainVideoMute = new MainVideoMute();
}
} }
public class Local : ValueProperty public class Local : ValueProperty
@@ -1881,7 +1875,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{ {
Selfview = new Selfview(); Selfview = new Selfview();
Layout = new Layout(); Layout = new Layout();
Input = new Input2();
} }
} }

View File

@@ -19,32 +19,4 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
void LocalLayoutToggleSingleProminent(); void LocalLayoutToggleSingleProminent();
void MinMaxLayoutToggle(); void MinMaxLayoutToggle();
} }
/// <summary>
/// Defines the requirements for Zoom Room layout control
/// </summary>
public interface IHasZoomRoomLayouts : IHasCodecLayouts
{
event EventHandler<LayoutInfoChangedEventArgs> AvailableLayoutsChanged;
BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func
BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func
BoolFeedback CanSwapContentWithThumbnailFeedback { get; }
BoolFeedback ContentSwappedWithThumbnailFeedback { get; }
ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; }
ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; }
void GetAvailableLayouts(); // Mot sure this is necessary if we're already subscribed to zStatus Call Layout
void SetLayout(ZoomRoom.zConfiguration.eLayoutStyle layoutStyle);
void SwapContentWithThumbnail();
void LayoutTurnNextPage();
void LayoutTurnPreviousPage();
}
public class LayoutInfoChangedEventArgs : EventArgs
{
public ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; set; }
}
} }

View File

@@ -1,20 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
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 public interface IHasParticipants
{ {
CodecParticipants Participants { get; } CodecParticipants Participants { get; }
} }
/// <summary>
/// Describes the ability to mute and unmute a participant's video in a meeting
/// </summary>
public interface IHasParticipantVideoMute:IHasParticipants public interface IHasParticipantVideoMute:IHasParticipants
{ {
void MuteVideoForParticipant(int userId); void MuteVideoForParticipant(int userId);
@@ -22,29 +15,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
void ToggleVideoForParticipant(int userId); void ToggleVideoForParticipant(int userId);
} }
/// <summary> public interface IHasParticipantAudioMute:IHasParticipantVideoMute
/// Describes the ability to mute and unmute a participant's audio in a meeting
/// </summary>
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
{ {
void MuteAudioForParticipant(int userId); void MuteAudioForParticipant(int userId);
void UnmuteAudioForParticipant(int userId); void UnmuteAudioForParticipant(int userId);
void ToggleAudioForParticipant(int userId); void ToggleAudioForParticipant(int userId);
} }
/// <summary>
/// Describes the ability to pin and unpin a participant in a meeting
/// </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);
}
public class CodecParticipants public class CodecParticipants
{ {
private List<Participant> _currentParticipants; private List<Participant> _currentParticipants;
@@ -54,7 +31,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
set set
{ {
_currentParticipants = value; _currentParticipants = value;
OnParticipantsChanged(); var handler = ParticipantsListHasChanged;
if(handler == null) return;
handler(this, new EventArgs());
} }
} }
@@ -64,31 +45,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{ {
_currentParticipants = new List<Participant>(); _currentParticipants = new List<Participant>();
} }
public void OnParticipantsChanged()
{
var handler = ParticipantsListHasChanged;
if (handler == null) return;
handler(this, new EventArgs());
}
} }
/// <summary>
/// Represents a call participant
/// </summary>
public class Participant public class Participant
{ {
public int UserId { get; set; }
public bool IsHost { get; set; } public bool IsHost { get; set; }
public string Name { get; set; } public string Name { get; set; }
public bool CanMuteVideo { get; set; } public bool CanMuteVideo { get; set; }
public bool CanUnmuteVideo { get; set; } public bool CanUnmuteVideo { get; set; }
public bool VideoMuteFb { get; set; } public bool VideoMuteFb { get; set; }
public bool AudioMuteFb { get; set; } public bool AudioMuteFb { get; set; }
public bool HandIsRaisedFb { get; set; }
public bool IsPinnedFb { get; set; }
public int ScreenIndexIsPinnedToFb { get; set; }
} }
} }

View File

@@ -28,7 +28,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
{ {
private const int XSigEncoding = 28591; private const int XSigEncoding = 28591;
protected const int MaxParticipants = 50;
private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs(); private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
protected VideoCodecBase(DeviceConfig config) protected VideoCodecBase(DeviceConfig config)
: base(config) : base(config)
@@ -272,14 +271,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
/// <summary>
/// Use this method when using a plain VideoCodecControllerJoinMap
/// </summary>
/// <param name="codec"></param>
/// <param name="trilist"></param>
/// <param name="joinStart"></param>
/// <param name="joinMapKey"></param>
/// <param name="bridge"></param>
protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey, protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey,
EiscApiAdvanced bridge) EiscApiAdvanced bridge)
{ {
@@ -297,19 +288,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
bridge.AddJoinMap(Key, joinMap); bridge.AddJoinMap(Key, joinMap);
} }
LinkVideoCodecToApi(codec, trilist, joinMap);
}
/// <summary>
/// Use this method when you need to pass in a join map that extends VideoCodecControllerJoinMap
/// </summary>
/// <param name="codec"></param>
/// <param name="trilist"></param>
/// <param name="joinMap"></param>
protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
{
Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X")); Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X"));
LinkVideoCodecDtmfToApi(trilist, joinMap); LinkVideoCodecDtmfToApi(trilist, joinMap);
LinkVideoCodecCallControlsToApi(trilist, joinMap); LinkVideoCodecCallControlsToApi(trilist, joinMap);
@@ -542,8 +524,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
return; return;
} }
SetParticipantActions(trilist, joinMap, codec.Participants.CurrentParticipants);
participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants); participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants);
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
@@ -552,59 +532,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
}; };
} }
/// <summary>
/// Sets the actions for each participant in the list
/// </summary>
private void SetParticipantActions(BasicTriList trilist, VideoCodecControllerJoinMap joinMap, List<Participant> currentParticipants)
{
uint index = 0; // track the index of the participant in the
foreach (var participant in currentParticipants)
{
var p = participant;
if (index > MaxParticipants) break;
var audioMuteCodec = this as IHasParticipantAudioMute;
if (audioMuteCodec != null)
{
trilist.SetSigFalseAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index,
() => audioMuteCodec.ToggleAudioForParticipant(p.UserId));
trilist.SetSigFalseAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index,
() => audioMuteCodec.ToggleVideoForParticipant(p.UserId));
}
var pinCodec = this as IHasParticipantPinUnpin;
if (pinCodec != null)
{
trilist.SetSigFalseAction(joinMap.ParticipantPinToggleStart.JoinNumber + index,
() => pinCodec.ToggleParticipantPinState(p.UserId, pinCodec.ScreenIndexToPinUserTo));
}
index++;
}
// Clear out any previously set actions
while (index < MaxParticipants)
{
trilist.ClearBoolSigAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index);
trilist.ClearBoolSigAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index);
trilist.ClearBoolSigAction(joinMap.ParticipantPinToggleStart.JoinNumber + index);
index++;
}
}
private string UpdateParticipantsXSig(List<Participant> currentParticipants) private string UpdateParticipantsXSig(List<Participant> currentParticipants)
{ {
const int maxParticipants = MaxParticipants; const int maxParticipants = 50;
const int maxDigitals = 7; const int maxDigitals = 5;
const int maxStrings = 1; const int maxStrings = 1;
const int maxAnalogs = 1; const int offset = maxDigitals + maxStrings;
const int offset = maxDigitals + maxStrings + maxAnalogs; // 9 var digitalIndex = maxStrings * maxParticipants; //15
var digitalIndex = (maxStrings + maxAnalogs) * maxParticipants; // 100
var stringIndex = 0; var stringIndex = 0;
var analogIndex = stringIndex + maxParticipants;
var meetingIndex = 0; var meetingIndex = 0;
var tokenArray = new XSigToken[maxParticipants * offset]; var tokenArray = new XSigToken[maxParticipants * offset];
@@ -619,42 +554,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo); tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo); tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost); tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb);
tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb);
//serials //serials
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name); tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
//analogs
tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, (ushort)participant.ScreenIndexIsPinnedToFb);
digitalIndex += maxDigitals; digitalIndex += maxDigitals;
meetingIndex += offset; meetingIndex += offset;
stringIndex += maxStrings; stringIndex += maxStrings;
analogIndex += maxAnalogs;
} }
while (meetingIndex < maxParticipants * offset) while (meetingIndex < maxParticipants * offset)
{ {
//digitals
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false); tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false); tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false); tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false);
tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, false);
tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, false);
//serials //serials
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
//analogs
tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, 0);
digitalIndex += maxDigitals; digitalIndex += maxDigitals;
meetingIndex += offset; meetingIndex += offset;
stringIndex += maxStrings; stringIndex += maxStrings;
analogIndex += maxAnalogs;
} }
return GetXSigString(tokenArray); return GetXSigString(tokenArray);
@@ -673,6 +595,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b); trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b);
} }
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
private List<Meeting> _currentMeetings = new List<Meeting>(); private List<Meeting> _currentMeetings = new List<Meeting>();
private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
@@ -684,6 +607,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
codec.CodecSchedule.MeetingWarningMinutes = i; codec.CodecSchedule.MeetingWarningMinutes = i;
}); });
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () => trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () =>
{ {
var mtg = 1; var mtg = 1;
@@ -693,7 +617,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
if (_currentMeetings[index] != null) if (_currentMeetings[index] != null)
Dial(_currentMeetings[index]); Dial(_currentMeetings[index]);
}); });
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () => trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () =>
{ {
var mtg = 2; var mtg = 2;
@@ -703,7 +627,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
if (_currentMeetings[index] != null) if (_currentMeetings[index] != null)
Dial(_currentMeetings[index]); Dial(_currentMeetings[index]);
}); });
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () => trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () =>
{ {
var mtg = 3; var mtg = 3;
@@ -728,8 +652,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
{ {
var currentTime = DateTime.Now; var currentTime = DateTime.Now;
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
// - changed var currentMeetings >> field _currentMeetings
//_currentMeetings.Clear();
_currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList(); _currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList();
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
// - moved the trilist.SetSigFlaseAction(joinMap.DialMeeting1..3.JoinNumber) lambda's to LinkVideoCodecScheduleToApi
var meetingsData = UpdateMeetingsListXSig(_currentMeetings); var meetingsData = UpdateMeetingsListXSig(_currentMeetings);
trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData); trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count); trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count);
@@ -917,7 +847,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction); Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction);
Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming); Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming);
trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status == eCodecCallStatus.Ringing); trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status == eCodecCallStatus.Ringing);
if (args.CallItem.Direction == eCodecCallDirection.Incoming) if (args.CallItem.Direction == eCodecCallDirection.Incoming)
{ {

View File

@@ -1,273 +0,0 @@
using System;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges.JoinMaps;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
public class ZoomRoomJoinMap : VideoCodecControllerJoinMap
{
// TODO: #697 [X] Set join numbers
#region Digital
[JoinName("CanSwapContentWithThumbnail")]
public JoinDataComplete CanSwapContentWithThumbnail = new JoinDataComplete(
new JoinData
{
JoinNumber = 206,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if content can be swapped with thumbnail",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("SwapContentWithThumbnail")]
public JoinDataComplete SwapContentWithThumbnail = new JoinDataComplete(
new JoinData
{
JoinNumber = 206,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Pulse to swap content with thumbnail. FB reports current state",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("GetAvailableLayouts")]
public JoinDataComplete GetAvailableLayouts = new JoinDataComplete(
new JoinData
{
JoinNumber = 215,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutIsOnFirstPage")]
public JoinDataComplete LayoutIsOnFirstPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 216,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Indicates if layout is on first page",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutIsOnLastPage")]
public JoinDataComplete LayoutIsOnLastPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 217,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Indicates if layout is on first page",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutTurnToNextPage")]
public JoinDataComplete LayoutTurnToNextPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 216,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Turns layout view to next page",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutTurnToPreviousPage")]
public JoinDataComplete LayoutTurnToPreviousPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 217,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Turns layout view to previous page",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutGalleryIsAvailable")]
public JoinDataComplete LayoutGalleryIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 221,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'Gallery' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutSpeakerIsAvailable")]
public JoinDataComplete LayoutSpeakerIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 222,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'Speaker' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutStripIsAvailable")]
public JoinDataComplete LayoutStripIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 223,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'Strip' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutShareAllIsAvailable")]
public JoinDataComplete LayoutShareAllIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 224,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'ShareAll' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
//[JoinName("ParticipantAudioMuteToggleStart")]
//public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 500,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's audio mute status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
//[JoinName("ParticipantVideoMuteToggleStart")]
//public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 800,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's video mute status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
//[JoinName("ParticipantPinToggleStart")]
//public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 1100,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's pin status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
#endregion
#region Analog
[JoinName("NumberOfScreens")]
public JoinDataComplete NumberOfScreens = new JoinDataComplete(
new JoinData
{
JoinNumber = 11,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Reports the number of screens connected",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("ScreenIndexToPinUserTo")]
public JoinDataComplete ScreenIndexToPinUserTo = new JoinDataComplete(
new JoinData
{
JoinNumber = 11,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Specifies the screen index a participant should be pinned to",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Analog
});
#endregion
#region Serials
[JoinName("GetSetCurrentLayout")]
public JoinDataComplete GetSetCurrentLayout = new JoinDataComplete(
new JoinData
{
JoinNumber = 215,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Serial
});
#endregion
public ZoomRoomJoinMap(uint joinStart)
: base(joinStart, typeof(ZoomRoomJoinMap))
{
}
public ZoomRoomJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}